1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2011 Marvell International Ltd. All rights reserved. |
4 | * Author: Chao Xie <chao.xie@marvell.com> |
5 | * Neil Zhang <zhangwm@marvell.com> |
6 | */ |
7 | |
8 | #include <linux/module.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/io.h> |
11 | #include <linux/iopoll.h> |
12 | #include <linux/uaccess.h> |
13 | #include <linux/device.h> |
14 | #include <linux/proc_fs.h> |
15 | #include <linux/clk.h> |
16 | #include <linux/workqueue.h> |
17 | #include <linux/platform_device.h> |
18 | |
19 | #include <linux/usb.h> |
20 | #include <linux/usb/ch9.h> |
21 | #include <linux/usb/otg.h> |
22 | #include <linux/usb/gadget.h> |
23 | #include <linux/usb/hcd.h> |
24 | #include <linux/platform_data/mv_usb.h> |
25 | |
26 | #include "phy-mv-usb.h" |
27 | |
28 | #define DRIVER_DESC "Marvell USB OTG transceiver driver" |
29 | |
30 | MODULE_DESCRIPTION(DRIVER_DESC); |
31 | MODULE_LICENSE("GPL" ); |
32 | |
33 | static const char driver_name[] = "mv-otg" ; |
34 | |
35 | static char *state_string[] = { |
36 | "undefined" , |
37 | "b_idle" , |
38 | "b_srp_init" , |
39 | "b_peripheral" , |
40 | "b_wait_acon" , |
41 | "b_host" , |
42 | "a_idle" , |
43 | "a_wait_vrise" , |
44 | "a_wait_bcon" , |
45 | "a_host" , |
46 | "a_suspend" , |
47 | "a_peripheral" , |
48 | "a_wait_vfall" , |
49 | "a_vbus_err" |
50 | }; |
51 | |
52 | static int mv_otg_set_vbus(struct usb_otg *otg, bool on) |
53 | { |
54 | struct mv_otg *mvotg = container_of(otg->usb_phy, struct mv_otg, phy); |
55 | if (mvotg->pdata->set_vbus == NULL) |
56 | return -ENODEV; |
57 | |
58 | return mvotg->pdata->set_vbus(on); |
59 | } |
60 | |
61 | static int mv_otg_set_host(struct usb_otg *otg, |
62 | struct usb_bus *host) |
63 | { |
64 | otg->host = host; |
65 | |
66 | return 0; |
67 | } |
68 | |
69 | static int mv_otg_set_peripheral(struct usb_otg *otg, |
70 | struct usb_gadget *gadget) |
71 | { |
72 | otg->gadget = gadget; |
73 | |
74 | return 0; |
75 | } |
76 | |
77 | static void mv_otg_run_state_machine(struct mv_otg *mvotg, |
78 | unsigned long delay) |
79 | { |
80 | dev_dbg(&mvotg->pdev->dev, "transceiver is updated\n" ); |
81 | if (!mvotg->qwork) |
82 | return; |
83 | |
84 | queue_delayed_work(wq: mvotg->qwork, dwork: &mvotg->work, delay); |
85 | } |
86 | |
87 | static void mv_otg_timer_await_bcon(struct timer_list *t) |
88 | { |
89 | struct mv_otg *mvotg = from_timer(mvotg, t, |
90 | otg_ctrl.timer[A_WAIT_BCON_TIMER]); |
91 | |
92 | mvotg->otg_ctrl.a_wait_bcon_timeout = 1; |
93 | |
94 | dev_info(&mvotg->pdev->dev, "B Device No Response!\n" ); |
95 | |
96 | if (spin_trylock(lock: &mvotg->wq_lock)) { |
97 | mv_otg_run_state_machine(mvotg, delay: 0); |
98 | spin_unlock(lock: &mvotg->wq_lock); |
99 | } |
100 | } |
101 | |
102 | static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id) |
103 | { |
104 | struct timer_list *timer; |
105 | |
106 | if (id >= OTG_TIMER_NUM) |
107 | return -EINVAL; |
108 | |
109 | timer = &mvotg->otg_ctrl.timer[id]; |
110 | |
111 | if (timer_pending(timer)) |
112 | del_timer(timer); |
113 | |
114 | return 0; |
115 | } |
116 | |
117 | static int mv_otg_set_timer(struct mv_otg *mvotg, unsigned int id, |
118 | unsigned long interval) |
119 | { |
120 | struct timer_list *timer; |
121 | |
122 | if (id >= OTG_TIMER_NUM) |
123 | return -EINVAL; |
124 | |
125 | timer = &mvotg->otg_ctrl.timer[id]; |
126 | if (timer_pending(timer)) { |
127 | dev_err(&mvotg->pdev->dev, "Timer%d is already running\n" , id); |
128 | return -EBUSY; |
129 | } |
130 | |
131 | timer->expires = jiffies + interval; |
132 | add_timer(timer); |
133 | |
134 | return 0; |
135 | } |
136 | |
137 | static int mv_otg_reset(struct mv_otg *mvotg) |
138 | { |
139 | u32 tmp; |
140 | int ret; |
141 | |
142 | /* Stop the controller */ |
143 | tmp = readl(addr: &mvotg->op_regs->usbcmd); |
144 | tmp &= ~USBCMD_RUN_STOP; |
145 | writel(val: tmp, addr: &mvotg->op_regs->usbcmd); |
146 | |
147 | /* Reset the controller to get default values */ |
148 | writel(USBCMD_CTRL_RESET, addr: &mvotg->op_regs->usbcmd); |
149 | |
150 | ret = readl_poll_timeout_atomic(&mvotg->op_regs->usbcmd, tmp, |
151 | (tmp & USBCMD_CTRL_RESET), 10, 10000); |
152 | if (ret < 0) { |
153 | dev_err(&mvotg->pdev->dev, |
154 | "Wait for RESET completed TIMEOUT\n" ); |
155 | return ret; |
156 | } |
157 | |
158 | writel(val: 0x0, addr: &mvotg->op_regs->usbintr); |
159 | tmp = readl(addr: &mvotg->op_regs->usbsts); |
160 | writel(val: tmp, addr: &mvotg->op_regs->usbsts); |
161 | |
162 | return 0; |
163 | } |
164 | |
165 | static void mv_otg_init_irq(struct mv_otg *mvotg) |
166 | { |
167 | u32 otgsc; |
168 | |
169 | mvotg->irq_en = OTGSC_INTR_A_SESSION_VALID |
170 | | OTGSC_INTR_A_VBUS_VALID; |
171 | mvotg->irq_status = OTGSC_INTSTS_A_SESSION_VALID |
172 | | OTGSC_INTSTS_A_VBUS_VALID; |
173 | |
174 | if (mvotg->pdata->vbus == NULL) { |
175 | mvotg->irq_en |= OTGSC_INTR_B_SESSION_VALID |
176 | | OTGSC_INTR_B_SESSION_END; |
177 | mvotg->irq_status |= OTGSC_INTSTS_B_SESSION_VALID |
178 | | OTGSC_INTSTS_B_SESSION_END; |
179 | } |
180 | |
181 | if (mvotg->pdata->id == NULL) { |
182 | mvotg->irq_en |= OTGSC_INTR_USB_ID; |
183 | mvotg->irq_status |= OTGSC_INTSTS_USB_ID; |
184 | } |
185 | |
186 | otgsc = readl(addr: &mvotg->op_regs->otgsc); |
187 | otgsc |= mvotg->irq_en; |
188 | writel(val: otgsc, addr: &mvotg->op_regs->otgsc); |
189 | } |
190 | |
191 | static void mv_otg_start_host(struct mv_otg *mvotg, int on) |
192 | { |
193 | #ifdef CONFIG_USB |
194 | struct usb_otg *otg = mvotg->phy.otg; |
195 | struct usb_hcd *hcd; |
196 | |
197 | if (!otg->host) |
198 | return; |
199 | |
200 | dev_info(&mvotg->pdev->dev, "%s host\n" , on ? "start" : "stop" ); |
201 | |
202 | hcd = bus_to_hcd(bus: otg->host); |
203 | |
204 | if (on) { |
205 | usb_add_hcd(hcd, irqnum: hcd->irq, IRQF_SHARED); |
206 | device_wakeup_enable(dev: hcd->self.controller); |
207 | } else { |
208 | usb_remove_hcd(hcd); |
209 | } |
210 | #endif /* CONFIG_USB */ |
211 | } |
212 | |
213 | static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) |
214 | { |
215 | struct usb_otg *otg = mvotg->phy.otg; |
216 | |
217 | if (!otg->gadget) |
218 | return; |
219 | |
220 | dev_info(mvotg->phy.dev, "gadget %s\n" , on ? "on" : "off" ); |
221 | |
222 | if (on) |
223 | usb_gadget_vbus_connect(gadget: otg->gadget); |
224 | else |
225 | usb_gadget_vbus_disconnect(gadget: otg->gadget); |
226 | } |
227 | |
228 | static void otg_clock_enable(struct mv_otg *mvotg) |
229 | { |
230 | clk_prepare_enable(clk: mvotg->clk); |
231 | } |
232 | |
233 | static void otg_clock_disable(struct mv_otg *mvotg) |
234 | { |
235 | clk_disable_unprepare(clk: mvotg->clk); |
236 | } |
237 | |
238 | static int mv_otg_enable_internal(struct mv_otg *mvotg) |
239 | { |
240 | int retval = 0; |
241 | |
242 | if (mvotg->active) |
243 | return 0; |
244 | |
245 | dev_dbg(&mvotg->pdev->dev, "otg enabled\n" ); |
246 | |
247 | otg_clock_enable(mvotg); |
248 | if (mvotg->pdata->phy_init) { |
249 | retval = mvotg->pdata->phy_init(mvotg->phy_regs); |
250 | if (retval) { |
251 | dev_err(&mvotg->pdev->dev, |
252 | "init phy error %d\n" , retval); |
253 | otg_clock_disable(mvotg); |
254 | return retval; |
255 | } |
256 | } |
257 | mvotg->active = 1; |
258 | |
259 | return 0; |
260 | |
261 | } |
262 | |
263 | static int mv_otg_enable(struct mv_otg *mvotg) |
264 | { |
265 | if (mvotg->clock_gating) |
266 | return mv_otg_enable_internal(mvotg); |
267 | |
268 | return 0; |
269 | } |
270 | |
271 | static void mv_otg_disable_internal(struct mv_otg *mvotg) |
272 | { |
273 | if (mvotg->active) { |
274 | dev_dbg(&mvotg->pdev->dev, "otg disabled\n" ); |
275 | if (mvotg->pdata->phy_deinit) |
276 | mvotg->pdata->phy_deinit(mvotg->phy_regs); |
277 | otg_clock_disable(mvotg); |
278 | mvotg->active = 0; |
279 | } |
280 | } |
281 | |
282 | static void mv_otg_disable(struct mv_otg *mvotg) |
283 | { |
284 | if (mvotg->clock_gating) |
285 | mv_otg_disable_internal(mvotg); |
286 | } |
287 | |
288 | static void mv_otg_update_inputs(struct mv_otg *mvotg) |
289 | { |
290 | struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; |
291 | u32 otgsc; |
292 | |
293 | otgsc = readl(addr: &mvotg->op_regs->otgsc); |
294 | |
295 | if (mvotg->pdata->vbus) { |
296 | if (mvotg->pdata->vbus->poll() == VBUS_HIGH) { |
297 | otg_ctrl->b_sess_vld = 1; |
298 | otg_ctrl->b_sess_end = 0; |
299 | } else { |
300 | otg_ctrl->b_sess_vld = 0; |
301 | otg_ctrl->b_sess_end = 1; |
302 | } |
303 | } else { |
304 | otg_ctrl->b_sess_vld = !!(otgsc & OTGSC_STS_B_SESSION_VALID); |
305 | otg_ctrl->b_sess_end = !!(otgsc & OTGSC_STS_B_SESSION_END); |
306 | } |
307 | |
308 | if (mvotg->pdata->id) |
309 | otg_ctrl->id = !!mvotg->pdata->id->poll(); |
310 | else |
311 | otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID); |
312 | |
313 | if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id) |
314 | otg_ctrl->a_bus_req = 1; |
315 | |
316 | otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID); |
317 | otg_ctrl->a_vbus_vld = !!(otgsc & OTGSC_STS_A_VBUS_VALID); |
318 | |
319 | dev_dbg(&mvotg->pdev->dev, "%s: " , __func__); |
320 | dev_dbg(&mvotg->pdev->dev, "id %d\n" , otg_ctrl->id); |
321 | dev_dbg(&mvotg->pdev->dev, "b_sess_vld %d\n" , otg_ctrl->b_sess_vld); |
322 | dev_dbg(&mvotg->pdev->dev, "b_sess_end %d\n" , otg_ctrl->b_sess_end); |
323 | dev_dbg(&mvotg->pdev->dev, "a_vbus_vld %d\n" , otg_ctrl->a_vbus_vld); |
324 | dev_dbg(&mvotg->pdev->dev, "a_sess_vld %d\n" , otg_ctrl->a_sess_vld); |
325 | } |
326 | |
327 | static void mv_otg_update_state(struct mv_otg *mvotg) |
328 | { |
329 | struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; |
330 | int old_state = mvotg->phy.otg->state; |
331 | |
332 | switch (old_state) { |
333 | case OTG_STATE_UNDEFINED: |
334 | mvotg->phy.otg->state = OTG_STATE_B_IDLE; |
335 | fallthrough; |
336 | case OTG_STATE_B_IDLE: |
337 | if (otg_ctrl->id == 0) |
338 | mvotg->phy.otg->state = OTG_STATE_A_IDLE; |
339 | else if (otg_ctrl->b_sess_vld) |
340 | mvotg->phy.otg->state = OTG_STATE_B_PERIPHERAL; |
341 | break; |
342 | case OTG_STATE_B_PERIPHERAL: |
343 | if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0) |
344 | mvotg->phy.otg->state = OTG_STATE_B_IDLE; |
345 | break; |
346 | case OTG_STATE_A_IDLE: |
347 | if (otg_ctrl->id) |
348 | mvotg->phy.otg->state = OTG_STATE_B_IDLE; |
349 | else if (!(otg_ctrl->a_bus_drop) && |
350 | (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det)) |
351 | mvotg->phy.otg->state = OTG_STATE_A_WAIT_VRISE; |
352 | break; |
353 | case OTG_STATE_A_WAIT_VRISE: |
354 | if (otg_ctrl->a_vbus_vld) |
355 | mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON; |
356 | break; |
357 | case OTG_STATE_A_WAIT_BCON: |
358 | if (otg_ctrl->id || otg_ctrl->a_bus_drop |
359 | || otg_ctrl->a_wait_bcon_timeout) { |
360 | mv_otg_cancel_timer(mvotg, id: A_WAIT_BCON_TIMER); |
361 | mvotg->otg_ctrl.a_wait_bcon_timeout = 0; |
362 | mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL; |
363 | otg_ctrl->a_bus_req = 0; |
364 | } else if (!otg_ctrl->a_vbus_vld) { |
365 | mv_otg_cancel_timer(mvotg, id: A_WAIT_BCON_TIMER); |
366 | mvotg->otg_ctrl.a_wait_bcon_timeout = 0; |
367 | mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR; |
368 | } else if (otg_ctrl->b_conn) { |
369 | mv_otg_cancel_timer(mvotg, id: A_WAIT_BCON_TIMER); |
370 | mvotg->otg_ctrl.a_wait_bcon_timeout = 0; |
371 | mvotg->phy.otg->state = OTG_STATE_A_HOST; |
372 | } |
373 | break; |
374 | case OTG_STATE_A_HOST: |
375 | if (otg_ctrl->id || !otg_ctrl->b_conn |
376 | || otg_ctrl->a_bus_drop) |
377 | mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON; |
378 | else if (!otg_ctrl->a_vbus_vld) |
379 | mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR; |
380 | break; |
381 | case OTG_STATE_A_WAIT_VFALL: |
382 | if (otg_ctrl->id |
383 | || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld) |
384 | || otg_ctrl->a_bus_req) |
385 | mvotg->phy.otg->state = OTG_STATE_A_IDLE; |
386 | break; |
387 | case OTG_STATE_A_VBUS_ERR: |
388 | if (otg_ctrl->id || otg_ctrl->a_clr_err |
389 | || otg_ctrl->a_bus_drop) { |
390 | otg_ctrl->a_clr_err = 0; |
391 | mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL; |
392 | } |
393 | break; |
394 | default: |
395 | break; |
396 | } |
397 | } |
398 | |
399 | static void mv_otg_work(struct work_struct *work) |
400 | { |
401 | struct mv_otg *mvotg; |
402 | struct usb_otg *otg; |
403 | int old_state; |
404 | |
405 | mvotg = container_of(to_delayed_work(work), struct mv_otg, work); |
406 | |
407 | run: |
408 | /* work queue is single thread, or we need spin_lock to protect */ |
409 | otg = mvotg->phy.otg; |
410 | old_state = otg->state; |
411 | |
412 | if (!mvotg->active) |
413 | return; |
414 | |
415 | mv_otg_update_inputs(mvotg); |
416 | mv_otg_update_state(mvotg); |
417 | |
418 | if (old_state != mvotg->phy.otg->state) { |
419 | dev_info(&mvotg->pdev->dev, "change from state %s to %s\n" , |
420 | state_string[old_state], |
421 | state_string[mvotg->phy.otg->state]); |
422 | |
423 | switch (mvotg->phy.otg->state) { |
424 | case OTG_STATE_B_IDLE: |
425 | otg->default_a = 0; |
426 | if (old_state == OTG_STATE_B_PERIPHERAL) |
427 | mv_otg_start_periphrals(mvotg, on: 0); |
428 | mv_otg_reset(mvotg); |
429 | mv_otg_disable(mvotg); |
430 | usb_phy_set_event(x: &mvotg->phy, event: USB_EVENT_NONE); |
431 | break; |
432 | case OTG_STATE_B_PERIPHERAL: |
433 | mv_otg_enable(mvotg); |
434 | mv_otg_start_periphrals(mvotg, on: 1); |
435 | usb_phy_set_event(x: &mvotg->phy, event: USB_EVENT_ENUMERATED); |
436 | break; |
437 | case OTG_STATE_A_IDLE: |
438 | otg->default_a = 1; |
439 | mv_otg_enable(mvotg); |
440 | if (old_state == OTG_STATE_A_WAIT_VFALL) |
441 | mv_otg_start_host(mvotg, on: 0); |
442 | mv_otg_reset(mvotg); |
443 | break; |
444 | case OTG_STATE_A_WAIT_VRISE: |
445 | mv_otg_set_vbus(otg, on: 1); |
446 | break; |
447 | case OTG_STATE_A_WAIT_BCON: |
448 | if (old_state != OTG_STATE_A_HOST) |
449 | mv_otg_start_host(mvotg, on: 1); |
450 | mv_otg_set_timer(mvotg, id: A_WAIT_BCON_TIMER, |
451 | T_A_WAIT_BCON); |
452 | /* |
453 | * Now, we directly enter A_HOST. So set b_conn = 1 |
454 | * here. In fact, it need host driver to notify us. |
455 | */ |
456 | mvotg->otg_ctrl.b_conn = 1; |
457 | break; |
458 | case OTG_STATE_A_HOST: |
459 | break; |
460 | case OTG_STATE_A_WAIT_VFALL: |
461 | /* |
462 | * Now, we has exited A_HOST. So set b_conn = 0 |
463 | * here. In fact, it need host driver to notify us. |
464 | */ |
465 | mvotg->otg_ctrl.b_conn = 0; |
466 | mv_otg_set_vbus(otg, on: 0); |
467 | break; |
468 | case OTG_STATE_A_VBUS_ERR: |
469 | break; |
470 | default: |
471 | break; |
472 | } |
473 | goto run; |
474 | } |
475 | } |
476 | |
477 | static irqreturn_t mv_otg_irq(int irq, void *dev) |
478 | { |
479 | struct mv_otg *mvotg = dev; |
480 | u32 otgsc; |
481 | |
482 | otgsc = readl(addr: &mvotg->op_regs->otgsc); |
483 | writel(val: otgsc, addr: &mvotg->op_regs->otgsc); |
484 | |
485 | /* |
486 | * if we have vbus, then the vbus detection for B-device |
487 | * will be done by mv_otg_inputs_irq(). |
488 | */ |
489 | if (mvotg->pdata->vbus) |
490 | if ((otgsc & OTGSC_STS_USB_ID) && |
491 | !(otgsc & OTGSC_INTSTS_USB_ID)) |
492 | return IRQ_NONE; |
493 | |
494 | if ((otgsc & mvotg->irq_status) == 0) |
495 | return IRQ_NONE; |
496 | |
497 | mv_otg_run_state_machine(mvotg, delay: 0); |
498 | |
499 | return IRQ_HANDLED; |
500 | } |
501 | |
502 | static irqreturn_t mv_otg_inputs_irq(int irq, void *dev) |
503 | { |
504 | struct mv_otg *mvotg = dev; |
505 | |
506 | /* The clock may disabled at this time */ |
507 | if (!mvotg->active) { |
508 | mv_otg_enable(mvotg); |
509 | mv_otg_init_irq(mvotg); |
510 | } |
511 | |
512 | mv_otg_run_state_machine(mvotg, delay: 0); |
513 | |
514 | return IRQ_HANDLED; |
515 | } |
516 | |
517 | static ssize_t |
518 | a_bus_req_show(struct device *dev, struct device_attribute *attr, char *buf) |
519 | { |
520 | struct mv_otg *mvotg = dev_get_drvdata(dev); |
521 | return scnprintf(buf, PAGE_SIZE, fmt: "%d\n" , |
522 | mvotg->otg_ctrl.a_bus_req); |
523 | } |
524 | |
525 | static ssize_t |
526 | a_bus_req_store(struct device *dev, struct device_attribute *attr, |
527 | const char *buf, size_t count) |
528 | { |
529 | struct mv_otg *mvotg = dev_get_drvdata(dev); |
530 | |
531 | if (count > 2) |
532 | return -1; |
533 | |
534 | /* We will use this interface to change to A device */ |
535 | if (mvotg->phy.otg->state != OTG_STATE_B_IDLE |
536 | && mvotg->phy.otg->state != OTG_STATE_A_IDLE) |
537 | return -1; |
538 | |
539 | /* The clock may disabled and we need to set irq for ID detected */ |
540 | mv_otg_enable(mvotg); |
541 | mv_otg_init_irq(mvotg); |
542 | |
543 | if (buf[0] == '1') { |
544 | mvotg->otg_ctrl.a_bus_req = 1; |
545 | mvotg->otg_ctrl.a_bus_drop = 0; |
546 | dev_dbg(&mvotg->pdev->dev, |
547 | "User request: a_bus_req = 1\n" ); |
548 | |
549 | if (spin_trylock(lock: &mvotg->wq_lock)) { |
550 | mv_otg_run_state_machine(mvotg, delay: 0); |
551 | spin_unlock(lock: &mvotg->wq_lock); |
552 | } |
553 | } |
554 | |
555 | return count; |
556 | } |
557 | |
558 | static DEVICE_ATTR_RW(a_bus_req); |
559 | |
560 | static ssize_t |
561 | a_clr_err_store(struct device *dev, struct device_attribute *attr, |
562 | const char *buf, size_t count) |
563 | { |
564 | struct mv_otg *mvotg = dev_get_drvdata(dev); |
565 | if (!mvotg->phy.otg->default_a) |
566 | return -1; |
567 | |
568 | if (count > 2) |
569 | return -1; |
570 | |
571 | if (buf[0] == '1') { |
572 | mvotg->otg_ctrl.a_clr_err = 1; |
573 | dev_dbg(&mvotg->pdev->dev, |
574 | "User request: a_clr_err = 1\n" ); |
575 | } |
576 | |
577 | if (spin_trylock(lock: &mvotg->wq_lock)) { |
578 | mv_otg_run_state_machine(mvotg, delay: 0); |
579 | spin_unlock(lock: &mvotg->wq_lock); |
580 | } |
581 | |
582 | return count; |
583 | } |
584 | |
585 | static DEVICE_ATTR_WO(a_clr_err); |
586 | |
587 | static ssize_t |
588 | a_bus_drop_show(struct device *dev, struct device_attribute *attr, |
589 | char *buf) |
590 | { |
591 | struct mv_otg *mvotg = dev_get_drvdata(dev); |
592 | return scnprintf(buf, PAGE_SIZE, fmt: "%d\n" , |
593 | mvotg->otg_ctrl.a_bus_drop); |
594 | } |
595 | |
596 | static ssize_t |
597 | a_bus_drop_store(struct device *dev, struct device_attribute *attr, |
598 | const char *buf, size_t count) |
599 | { |
600 | struct mv_otg *mvotg = dev_get_drvdata(dev); |
601 | if (!mvotg->phy.otg->default_a) |
602 | return -1; |
603 | |
604 | if (count > 2) |
605 | return -1; |
606 | |
607 | if (buf[0] == '0') { |
608 | mvotg->otg_ctrl.a_bus_drop = 0; |
609 | dev_dbg(&mvotg->pdev->dev, |
610 | "User request: a_bus_drop = 0\n" ); |
611 | } else if (buf[0] == '1') { |
612 | mvotg->otg_ctrl.a_bus_drop = 1; |
613 | mvotg->otg_ctrl.a_bus_req = 0; |
614 | dev_dbg(&mvotg->pdev->dev, |
615 | "User request: a_bus_drop = 1\n" ); |
616 | dev_dbg(&mvotg->pdev->dev, |
617 | "User request: and a_bus_req = 0\n" ); |
618 | } |
619 | |
620 | if (spin_trylock(lock: &mvotg->wq_lock)) { |
621 | mv_otg_run_state_machine(mvotg, delay: 0); |
622 | spin_unlock(lock: &mvotg->wq_lock); |
623 | } |
624 | |
625 | return count; |
626 | } |
627 | |
628 | static DEVICE_ATTR_RW(a_bus_drop); |
629 | |
630 | static struct attribute *inputs_attrs[] = { |
631 | &dev_attr_a_bus_req.attr, |
632 | &dev_attr_a_clr_err.attr, |
633 | &dev_attr_a_bus_drop.attr, |
634 | NULL, |
635 | }; |
636 | |
637 | static const struct attribute_group inputs_attr_group = { |
638 | .name = "inputs" , |
639 | .attrs = inputs_attrs, |
640 | }; |
641 | |
642 | static const struct attribute_group *mv_otg_groups[] = { |
643 | &inputs_attr_group, |
644 | NULL, |
645 | }; |
646 | |
647 | static void mv_otg_remove(struct platform_device *pdev) |
648 | { |
649 | struct mv_otg *mvotg = platform_get_drvdata(pdev); |
650 | |
651 | if (mvotg->qwork) |
652 | destroy_workqueue(wq: mvotg->qwork); |
653 | |
654 | mv_otg_disable(mvotg); |
655 | |
656 | usb_remove_phy(&mvotg->phy); |
657 | } |
658 | |
659 | static int mv_otg_probe(struct platform_device *pdev) |
660 | { |
661 | struct mv_usb_platform_data *pdata = dev_get_platdata(dev: &pdev->dev); |
662 | struct mv_otg *mvotg; |
663 | struct usb_otg *otg; |
664 | struct resource *r; |
665 | int retval = 0, i; |
666 | |
667 | if (pdata == NULL) { |
668 | dev_err(&pdev->dev, "failed to get platform data\n" ); |
669 | return -ENODEV; |
670 | } |
671 | |
672 | mvotg = devm_kzalloc(dev: &pdev->dev, size: sizeof(*mvotg), GFP_KERNEL); |
673 | if (!mvotg) |
674 | return -ENOMEM; |
675 | |
676 | otg = devm_kzalloc(dev: &pdev->dev, size: sizeof(*otg), GFP_KERNEL); |
677 | if (!otg) |
678 | return -ENOMEM; |
679 | |
680 | platform_set_drvdata(pdev, data: mvotg); |
681 | |
682 | mvotg->pdev = pdev; |
683 | mvotg->pdata = pdata; |
684 | |
685 | mvotg->clk = devm_clk_get(dev: &pdev->dev, NULL); |
686 | if (IS_ERR(ptr: mvotg->clk)) |
687 | return PTR_ERR(ptr: mvotg->clk); |
688 | |
689 | mvotg->qwork = create_singlethread_workqueue("mv_otg_queue" ); |
690 | if (!mvotg->qwork) { |
691 | dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n" ); |
692 | return -ENOMEM; |
693 | } |
694 | |
695 | INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); |
696 | |
697 | /* OTG common part */ |
698 | mvotg->pdev = pdev; |
699 | mvotg->phy.dev = &pdev->dev; |
700 | mvotg->phy.otg = otg; |
701 | mvotg->phy.label = driver_name; |
702 | |
703 | otg->state = OTG_STATE_UNDEFINED; |
704 | otg->usb_phy = &mvotg->phy; |
705 | otg->set_host = mv_otg_set_host; |
706 | otg->set_peripheral = mv_otg_set_peripheral; |
707 | otg->set_vbus = mv_otg_set_vbus; |
708 | |
709 | for (i = 0; i < OTG_TIMER_NUM; i++) |
710 | timer_setup(&mvotg->otg_ctrl.timer[i], |
711 | mv_otg_timer_await_bcon, 0); |
712 | |
713 | r = platform_get_resource_byname(mvotg->pdev, |
714 | IORESOURCE_MEM, "phyregs" ); |
715 | if (r == NULL) { |
716 | dev_err(&pdev->dev, "no phy I/O memory resource defined\n" ); |
717 | retval = -ENODEV; |
718 | goto err_destroy_workqueue; |
719 | } |
720 | |
721 | mvotg->phy_regs = devm_ioremap(dev: &pdev->dev, offset: r->start, size: resource_size(res: r)); |
722 | if (mvotg->phy_regs == NULL) { |
723 | dev_err(&pdev->dev, "failed to map phy I/O memory\n" ); |
724 | retval = -EFAULT; |
725 | goto err_destroy_workqueue; |
726 | } |
727 | |
728 | r = platform_get_resource_byname(mvotg->pdev, |
729 | IORESOURCE_MEM, "capregs" ); |
730 | if (r == NULL) { |
731 | dev_err(&pdev->dev, "no I/O memory resource defined\n" ); |
732 | retval = -ENODEV; |
733 | goto err_destroy_workqueue; |
734 | } |
735 | |
736 | mvotg->cap_regs = devm_ioremap(dev: &pdev->dev, offset: r->start, size: resource_size(res: r)); |
737 | if (mvotg->cap_regs == NULL) { |
738 | dev_err(&pdev->dev, "failed to map I/O memory\n" ); |
739 | retval = -EFAULT; |
740 | goto err_destroy_workqueue; |
741 | } |
742 | |
743 | /* we will acces controller register, so enable the udc controller */ |
744 | retval = mv_otg_enable_internal(mvotg); |
745 | if (retval) { |
746 | dev_err(&pdev->dev, "mv otg enable error %d\n" , retval); |
747 | goto err_destroy_workqueue; |
748 | } |
749 | |
750 | mvotg->op_regs = |
751 | (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs |
752 | + (readl(addr: mvotg->cap_regs) & CAPLENGTH_MASK)); |
753 | |
754 | if (pdata->id) { |
755 | retval = devm_request_threaded_irq(dev: &pdev->dev, irq: pdata->id->irq, |
756 | NULL, thread_fn: mv_otg_inputs_irq, |
757 | IRQF_ONESHOT, devname: "id" , dev_id: mvotg); |
758 | if (retval) { |
759 | dev_info(&pdev->dev, |
760 | "Failed to request irq for ID\n" ); |
761 | pdata->id = NULL; |
762 | } |
763 | } |
764 | |
765 | if (pdata->vbus) { |
766 | mvotg->clock_gating = 1; |
767 | retval = devm_request_threaded_irq(dev: &pdev->dev, irq: pdata->vbus->irq, |
768 | NULL, thread_fn: mv_otg_inputs_irq, |
769 | IRQF_ONESHOT, devname: "vbus" , dev_id: mvotg); |
770 | if (retval) { |
771 | dev_info(&pdev->dev, |
772 | "Failed to request irq for VBUS, " |
773 | "disable clock gating\n" ); |
774 | mvotg->clock_gating = 0; |
775 | pdata->vbus = NULL; |
776 | } |
777 | } |
778 | |
779 | if (pdata->disable_otg_clock_gating) |
780 | mvotg->clock_gating = 0; |
781 | |
782 | mv_otg_reset(mvotg); |
783 | mv_otg_init_irq(mvotg); |
784 | |
785 | r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0); |
786 | if (r == NULL) { |
787 | dev_err(&pdev->dev, "no IRQ resource defined\n" ); |
788 | retval = -ENODEV; |
789 | goto err_disable_clk; |
790 | } |
791 | |
792 | mvotg->irq = r->start; |
793 | if (devm_request_irq(dev: &pdev->dev, irq: mvotg->irq, handler: mv_otg_irq, IRQF_SHARED, |
794 | devname: driver_name, dev_id: mvotg)) { |
795 | dev_err(&pdev->dev, "Request irq %d for OTG failed\n" , |
796 | mvotg->irq); |
797 | mvotg->irq = 0; |
798 | retval = -ENODEV; |
799 | goto err_disable_clk; |
800 | } |
801 | |
802 | retval = usb_add_phy(&mvotg->phy, type: USB_PHY_TYPE_USB2); |
803 | if (retval < 0) { |
804 | dev_err(&pdev->dev, "can't register transceiver, %d\n" , |
805 | retval); |
806 | goto err_disable_clk; |
807 | } |
808 | |
809 | spin_lock_init(&mvotg->wq_lock); |
810 | if (spin_trylock(lock: &mvotg->wq_lock)) { |
811 | mv_otg_run_state_machine(mvotg, delay: 2 * HZ); |
812 | spin_unlock(lock: &mvotg->wq_lock); |
813 | } |
814 | |
815 | dev_info(&pdev->dev, |
816 | "successful probe OTG device %s clock gating.\n" , |
817 | mvotg->clock_gating ? "with" : "without" ); |
818 | |
819 | return 0; |
820 | |
821 | err_disable_clk: |
822 | mv_otg_disable_internal(mvotg); |
823 | err_destroy_workqueue: |
824 | destroy_workqueue(wq: mvotg->qwork); |
825 | |
826 | return retval; |
827 | } |
828 | |
829 | #ifdef CONFIG_PM |
830 | static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) |
831 | { |
832 | struct mv_otg *mvotg = platform_get_drvdata(pdev); |
833 | |
834 | if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) { |
835 | dev_info(&pdev->dev, |
836 | "OTG state is not B_IDLE, it is %d!\n" , |
837 | mvotg->phy.otg->state); |
838 | return -EAGAIN; |
839 | } |
840 | |
841 | if (!mvotg->clock_gating) |
842 | mv_otg_disable_internal(mvotg); |
843 | |
844 | return 0; |
845 | } |
846 | |
847 | static int mv_otg_resume(struct platform_device *pdev) |
848 | { |
849 | struct mv_otg *mvotg = platform_get_drvdata(pdev); |
850 | u32 otgsc; |
851 | |
852 | if (!mvotg->clock_gating) { |
853 | mv_otg_enable_internal(mvotg); |
854 | |
855 | otgsc = readl(addr: &mvotg->op_regs->otgsc); |
856 | otgsc |= mvotg->irq_en; |
857 | writel(val: otgsc, addr: &mvotg->op_regs->otgsc); |
858 | |
859 | if (spin_trylock(lock: &mvotg->wq_lock)) { |
860 | mv_otg_run_state_machine(mvotg, delay: 0); |
861 | spin_unlock(lock: &mvotg->wq_lock); |
862 | } |
863 | } |
864 | return 0; |
865 | } |
866 | #endif |
867 | |
868 | static struct platform_driver mv_otg_driver = { |
869 | .probe = mv_otg_probe, |
870 | .remove_new = mv_otg_remove, |
871 | .driver = { |
872 | .name = driver_name, |
873 | .dev_groups = mv_otg_groups, |
874 | }, |
875 | #ifdef CONFIG_PM |
876 | .suspend = mv_otg_suspend, |
877 | .resume = mv_otg_resume, |
878 | #endif |
879 | }; |
880 | module_platform_driver(mv_otg_driver); |
881 | |