1
2
3
4
5
6
7
8
9#include <linux/clk.h>
10#include <linux/err.h>
11#include <linux/gpio/consumer.h>
12#include <linux/io.h>
13#include <linux/module.h>
14#include <linux/of_device.h>
15#include <linux/pm_runtime.h>
16#include <linux/reset.h>
17#include <linux/slab.h>
18#include <linux/sysfs.h>
19#include "common.h"
20#include "rcar2.h"
21#include "rcar3.h"
22#include "rza.h"
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#define usbhs_platform_call(priv, func, args...)\
54 (!(priv) ? -ENODEV : \
55 !((priv)->pfunc->func) ? 0 : \
56 (priv)->pfunc->func(args))
57
58
59
60
61u16 usbhs_read(struct usbhs_priv *priv, u32 reg)
62{
63 return ioread16(priv->base + reg);
64}
65
66void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data)
67{
68 iowrite16(data, priv->base + reg);
69}
70
71void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data)
72{
73 u16 val = usbhs_read(priv, reg);
74
75 val &= ~mask;
76 val |= data & mask;
77
78 usbhs_write(priv, reg, val);
79}
80
81struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev)
82{
83 return dev_get_drvdata(&pdev->dev);
84}
85
86int usbhs_get_id_as_gadget(struct platform_device *pdev)
87{
88 return USBHS_GADGET;
89}
90
91
92
93
94static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
95{
96 usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0);
97}
98
99void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
100{
101 u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
102 u16 val = DCFM | DRPD | HSE | USBE;
103
104
105
106
107
108
109
110 usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
111}
112
113void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
114{
115 u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
116 u16 val = HSE | USBE;
117
118
119 if (usbhs_get_dparam(priv, has_cnen)) {
120 mask |= CNEN;
121 val |= CNEN;
122 }
123
124
125
126
127
128
129
130
131
132 usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
133}
134
135void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable)
136{
137 usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0);
138}
139
140void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode)
141{
142 usbhs_write(priv, TESTMODE, mode);
143}
144
145
146
147
148int usbhs_frame_get_num(struct usbhs_priv *priv)
149{
150 return usbhs_read(priv, FRMNUM) & FRNM_MASK;
151}
152
153
154
155
156void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
157{
158 u16 val;
159
160 val = usbhs_read(priv, USBREQ);
161 req->bRequest = (val >> 8) & 0xFF;
162 req->bRequestType = (val >> 0) & 0xFF;
163
164 req->wValue = cpu_to_le16(usbhs_read(priv, USBVAL));
165 req->wIndex = cpu_to_le16(usbhs_read(priv, USBINDX));
166 req->wLength = cpu_to_le16(usbhs_read(priv, USBLENG));
167}
168
169void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
170{
171 usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType);
172 usbhs_write(priv, USBVAL, le16_to_cpu(req->wValue));
173 usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex));
174 usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength));
175
176 usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
177}
178
179
180
181
182void usbhs_bus_send_sof_enable(struct usbhs_priv *priv)
183{
184 u16 status = usbhs_read(priv, DVSTCTR) & (USBRST | UACT);
185
186 if (status != USBRST) {
187 struct device *dev = usbhs_priv_to_dev(priv);
188 dev_err(dev, "usbhs should be reset\n");
189 }
190
191 usbhs_bset(priv, DVSTCTR, (USBRST | UACT), UACT);
192}
193
194void usbhs_bus_send_reset(struct usbhs_priv *priv)
195{
196 usbhs_bset(priv, DVSTCTR, (USBRST | UACT), USBRST);
197}
198
199int usbhs_bus_get_speed(struct usbhs_priv *priv)
200{
201 u16 dvstctr = usbhs_read(priv, DVSTCTR);
202
203 switch (RHST & dvstctr) {
204 case RHST_LOW_SPEED:
205 return USB_SPEED_LOW;
206 case RHST_FULL_SPEED:
207 return USB_SPEED_FULL;
208 case RHST_HIGH_SPEED:
209 return USB_SPEED_HIGH;
210 }
211
212 return USB_SPEED_UNKNOWN;
213}
214
215int usbhs_vbus_ctrl(struct usbhs_priv *priv, int enable)
216{
217 struct platform_device *pdev = usbhs_priv_to_pdev(priv);
218
219 return usbhs_platform_call(priv, set_vbus, pdev, enable);
220}
221
222static void usbhsc_bus_init(struct usbhs_priv *priv)
223{
224 usbhs_write(priv, DVSTCTR, 0);
225
226 usbhs_vbus_ctrl(priv, 0);
227}
228
229
230
231
232int usbhs_set_device_config(struct usbhs_priv *priv, int devnum,
233 u16 upphub, u16 hubport, u16 speed)
234{
235 struct device *dev = usbhs_priv_to_dev(priv);
236 u16 usbspd = 0;
237 u32 reg = DEVADD0 + (2 * devnum);
238
239 if (devnum > 10) {
240 dev_err(dev, "cannot set speed to unknown device %d\n", devnum);
241 return -EIO;
242 }
243
244 if (upphub > 0xA) {
245 dev_err(dev, "unsupported hub number %d\n", upphub);
246 return -EIO;
247 }
248
249 switch (speed) {
250 case USB_SPEED_LOW:
251 usbspd = USBSPD_SPEED_LOW;
252 break;
253 case USB_SPEED_FULL:
254 usbspd = USBSPD_SPEED_FULL;
255 break;
256 case USB_SPEED_HIGH:
257 usbspd = USBSPD_SPEED_HIGH;
258 break;
259 default:
260 dev_err(dev, "unsupported speed %d\n", speed);
261 return -EIO;
262 }
263
264 usbhs_write(priv, reg, UPPHUB(upphub) |
265 HUBPORT(hubport)|
266 USBSPD(usbspd));
267
268 return 0;
269}
270
271
272
273
274void usbhs_xxxsts_clear(struct usbhs_priv *priv, u16 sts_reg, u16 bit)
275{
276 u16 pipe_mask = (u16)GENMASK(usbhs_get_dparam(priv, pipe_size), 0);
277
278 usbhs_write(priv, sts_reg, ~(1 << bit) & pipe_mask);
279}
280
281
282
283
284static void usbhsc_set_buswait(struct usbhs_priv *priv)
285{
286 int wait = usbhs_get_dparam(priv, buswait_bwait);
287
288
289 if (wait)
290 usbhs_bset(priv, BUSWAIT, 0x000F, wait);
291}
292
293static bool usbhsc_is_multi_clks(struct usbhs_priv *priv)
294{
295 return priv->dparam.multi_clks;
296}
297
298static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv)
299{
300 if (!usbhsc_is_multi_clks(priv))
301 return 0;
302
303
304 priv->clks[0] = of_clk_get(dev_of_node(dev), 0);
305 if (IS_ERR(priv->clks[0]))
306 return PTR_ERR(priv->clks[0]);
307
308
309
310
311
312 priv->clks[1] = of_clk_get(dev_of_node(dev), 1);
313 if (PTR_ERR(priv->clks[1]) == -ENOENT)
314 priv->clks[1] = NULL;
315 else if (IS_ERR(priv->clks[1]))
316 return PTR_ERR(priv->clks[1]);
317
318 return 0;
319}
320
321static void usbhsc_clk_put(struct usbhs_priv *priv)
322{
323 int i;
324
325 if (!usbhsc_is_multi_clks(priv))
326 return;
327
328 for (i = 0; i < ARRAY_SIZE(priv->clks); i++)
329 clk_put(priv->clks[i]);
330}
331
332static int usbhsc_clk_prepare_enable(struct usbhs_priv *priv)
333{
334 int i, ret;
335
336 if (!usbhsc_is_multi_clks(priv))
337 return 0;
338
339 for (i = 0; i < ARRAY_SIZE(priv->clks); i++) {
340 ret = clk_prepare_enable(priv->clks[i]);
341 if (ret) {
342 while (--i >= 0)
343 clk_disable_unprepare(priv->clks[i]);
344 return ret;
345 }
346 }
347
348 return ret;
349}
350
351static void usbhsc_clk_disable_unprepare(struct usbhs_priv *priv)
352{
353 int i;
354
355 if (!usbhsc_is_multi_clks(priv))
356 return;
357
358 for (i = 0; i < ARRAY_SIZE(priv->clks); i++)
359 clk_disable_unprepare(priv->clks[i]);
360}
361
362
363
364
365
366
367static struct renesas_usbhs_driver_pipe_config usbhsc_default_pipe[] = {
368 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false),
369 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, false),
370 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x18, false),
371 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x28, true),
372 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x38, true),
373 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true),
374 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false),
375 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false),
376 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false),
377 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x07, false),
378};
379
380
381static struct renesas_usbhs_driver_pipe_config usbhsc_new_pipe[] = {
382 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false),
383 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, true),
384 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x28, true),
385 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true),
386 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x58, true),
387 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x68, true),
388 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false),
389 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false),
390 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false),
391 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x78, true),
392 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x88, true),
393 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x98, true),
394 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xa8, true),
395 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xb8, true),
396 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xc8, true),
397 RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xd8, true),
398};
399
400
401
402
403static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable)
404{
405 struct platform_device *pdev = usbhs_priv_to_pdev(priv);
406 struct device *dev = usbhs_priv_to_dev(priv);
407
408 if (enable) {
409
410 pm_runtime_get_sync(dev);
411
412
413 if (usbhsc_clk_prepare_enable(priv))
414 return;
415
416
417 usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
418
419
420 usbhs_sys_clock_ctrl(priv, enable);
421 } else {
422
423 usbhs_sys_clock_ctrl(priv, enable);
424
425
426 usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
427
428
429 usbhsc_clk_disable_unprepare(priv);
430
431
432 pm_runtime_put_sync(dev);
433 }
434}
435
436
437
438
439static void usbhsc_hotplug(struct usbhs_priv *priv)
440{
441 struct platform_device *pdev = usbhs_priv_to_pdev(priv);
442 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
443 int id;
444 int enable;
445 int cable;
446 int ret;
447
448
449
450
451 enable = usbhs_mod_info_call(priv, get_vbus, pdev);
452
453
454
455
456 id = usbhs_platform_call(priv, get_id, pdev);
457
458 if (enable && !mod) {
459 if (priv->edev) {
460 cable = extcon_get_state(priv->edev, EXTCON_USB_HOST);
461 if ((cable > 0 && id != USBHS_HOST) ||
462 (!cable && id != USBHS_GADGET)) {
463 dev_info(&pdev->dev,
464 "USB cable plugged in doesn't match the selected role!\n");
465 return;
466 }
467 }
468
469 ret = usbhs_mod_change(priv, id);
470 if (ret < 0)
471 return;
472
473 dev_dbg(&pdev->dev, "%s enable\n", __func__);
474
475
476 if (usbhs_get_dparam(priv, runtime_pwctrl))
477 usbhsc_power_ctrl(priv, enable);
478
479
480 usbhsc_set_buswait(priv);
481 usbhsc_bus_init(priv);
482
483
484 usbhs_mod_call(priv, start, priv);
485
486 } else if (!enable && mod) {
487 dev_dbg(&pdev->dev, "%s disable\n", __func__);
488
489
490 usbhs_mod_call(priv, stop, priv);
491
492
493 usbhsc_bus_init(priv);
494
495
496 if (usbhs_get_dparam(priv, runtime_pwctrl))
497 usbhsc_power_ctrl(priv, enable);
498
499 usbhs_mod_change(priv, -1);
500
501
502 usbhs_platform_call(priv, phy_reset, pdev);
503 }
504}
505
506
507
508
509static void usbhsc_notify_hotplug(struct work_struct *work)
510{
511 struct usbhs_priv *priv = container_of(work,
512 struct usbhs_priv,
513 notify_hotplug_work.work);
514 usbhsc_hotplug(priv);
515}
516
517int usbhsc_schedule_notify_hotplug(struct platform_device *pdev)
518{
519 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
520 int delay = usbhs_get_dparam(priv, detection_delay);
521
522
523
524
525
526
527 schedule_delayed_work(&priv->notify_hotplug_work,
528 msecs_to_jiffies(delay));
529 return 0;
530}
531
532
533
534
535static const struct of_device_id usbhs_of_match[] = {
536 {
537 .compatible = "renesas,usbhs-r8a774c0",
538 .data = &usbhs_rcar_gen3_with_pll_plat_info,
539 },
540 {
541 .compatible = "renesas,usbhs-r8a7790",
542 .data = &usbhs_rcar_gen2_plat_info,
543 },
544 {
545 .compatible = "renesas,usbhs-r8a7791",
546 .data = &usbhs_rcar_gen2_plat_info,
547 },
548 {
549 .compatible = "renesas,usbhs-r8a7794",
550 .data = &usbhs_rcar_gen2_plat_info,
551 },
552 {
553 .compatible = "renesas,usbhs-r8a7795",
554 .data = &usbhs_rcar_gen3_plat_info,
555 },
556 {
557 .compatible = "renesas,usbhs-r8a7796",
558 .data = &usbhs_rcar_gen3_plat_info,
559 },
560 {
561 .compatible = "renesas,usbhs-r8a77990",
562 .data = &usbhs_rcar_gen3_with_pll_plat_info,
563 },
564 {
565 .compatible = "renesas,usbhs-r8a77995",
566 .data = &usbhs_rcar_gen3_with_pll_plat_info,
567 },
568 {
569 .compatible = "renesas,rcar-gen2-usbhs",
570 .data = &usbhs_rcar_gen2_plat_info,
571 },
572 {
573 .compatible = "renesas,rcar-gen3-usbhs",
574 .data = &usbhs_rcar_gen3_plat_info,
575 },
576 {
577 .compatible = "renesas,rza1-usbhs",
578 .data = &usbhs_rza1_plat_info,
579 },
580 {
581 .compatible = "renesas,rza2-usbhs",
582 .data = &usbhs_rza2_plat_info,
583 },
584 { },
585};
586MODULE_DEVICE_TABLE(of, usbhs_of_match);
587
588static int usbhs_probe(struct platform_device *pdev)
589{
590 const struct renesas_usbhs_platform_info *info;
591 struct usbhs_priv *priv;
592 struct resource *irq_res;
593 struct device *dev = &pdev->dev;
594 struct gpio_desc *gpiod;
595 int ret;
596 u32 tmp;
597
598
599 if (dev_of_node(dev))
600 info = of_device_get_match_data(dev);
601 else
602 info = renesas_usbhs_get_info(pdev);
603
604
605 if (!info) {
606 dev_err(dev, "no platform information\n");
607 return -EINVAL;
608 }
609
610
611 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
612 if (!irq_res) {
613 dev_err(dev, "Not enough Renesas USB platform resources.\n");
614 return -ENODEV;
615 }
616
617
618 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
619 if (!priv)
620 return -ENOMEM;
621
622 priv->base = devm_platform_ioremap_resource(pdev, 0);
623 if (IS_ERR(priv->base))
624 return PTR_ERR(priv->base);
625
626 if (of_property_read_bool(dev_of_node(dev), "extcon")) {
627 priv->edev = extcon_get_edev_by_phandle(dev, 0);
628 if (IS_ERR(priv->edev))
629 return PTR_ERR(priv->edev);
630 }
631
632 priv->rsts = devm_reset_control_array_get_optional_shared(dev);
633 if (IS_ERR(priv->rsts))
634 return PTR_ERR(priv->rsts);
635
636
637
638
639
640 priv->dparam = info->driver_param;
641
642 if (!info->platform_callback.get_id) {
643 dev_err(dev, "no platform callbacks\n");
644 return -EINVAL;
645 }
646 priv->pfunc = &info->platform_callback;
647
648
649 if (usbhs_get_dparam(priv, has_new_pipe_configs)) {
650 priv->dparam.pipe_configs = usbhsc_new_pipe;
651 priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
652 } else if (!priv->dparam.pipe_configs) {
653 priv->dparam.pipe_configs = usbhsc_default_pipe;
654 priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe);
655 }
656 if (!priv->dparam.pio_dma_border)
657 priv->dparam.pio_dma_border = 64;
658 if (!of_property_read_u32(dev_of_node(dev), "renesas,buswait", &tmp))
659 priv->dparam.buswait_bwait = tmp;
660 gpiod = devm_gpiod_get_optional(dev, "renesas,enable", GPIOD_IN);
661 if (IS_ERR(gpiod))
662 return PTR_ERR(gpiod);
663
664
665
666 if (priv->pfunc->get_vbus)
667 usbhs_get_dparam(priv, runtime_pwctrl) = 1;
668
669
670
671
672 priv->irq = irq_res->start;
673 if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE)
674 priv->irqflags = IRQF_SHARED;
675 priv->pdev = pdev;
676 INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
677 spin_lock_init(usbhs_priv_to_lock(priv));
678
679
680 ret = usbhs_pipe_probe(priv);
681 if (ret < 0)
682 return ret;
683
684 ret = usbhs_fifo_probe(priv);
685 if (ret < 0)
686 goto probe_end_pipe_exit;
687
688 ret = usbhs_mod_probe(priv);
689 if (ret < 0)
690 goto probe_end_fifo_exit;
691
692
693 platform_set_drvdata(pdev, priv);
694
695 ret = reset_control_deassert(priv->rsts);
696 if (ret)
697 goto probe_fail_rst;
698
699 ret = usbhsc_clk_get(dev, priv);
700 if (ret)
701 goto probe_fail_clks;
702
703
704
705
706
707 usbhs_sys_clock_ctrl(priv, 0);
708
709
710 if (gpiod) {
711 ret = !gpiod_get_value(gpiod);
712 if (ret) {
713 dev_warn(dev, "USB function not selected (GPIO)\n");
714 ret = -ENOTSUPP;
715 goto probe_end_mod_exit;
716 }
717 }
718
719
720
721
722
723
724
725
726 ret = usbhs_platform_call(priv, hardware_init, pdev);
727 if (ret < 0) {
728 dev_err(dev, "platform init failed.\n");
729 goto probe_end_mod_exit;
730 }
731
732
733 usbhs_platform_call(priv, phy_reset, pdev);
734
735
736 pm_runtime_enable(dev);
737 if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
738 usbhsc_power_ctrl(priv, 1);
739 usbhs_mod_autonomy_mode(priv);
740 } else {
741 usbhs_mod_non_autonomy_mode(priv);
742 }
743
744
745
746
747 usbhsc_schedule_notify_hotplug(pdev);
748
749 dev_info(dev, "probed\n");
750
751 return ret;
752
753probe_end_mod_exit:
754 usbhsc_clk_put(priv);
755probe_fail_clks:
756 reset_control_assert(priv->rsts);
757probe_fail_rst:
758 usbhs_mod_remove(priv);
759probe_end_fifo_exit:
760 usbhs_fifo_remove(priv);
761probe_end_pipe_exit:
762 usbhs_pipe_remove(priv);
763
764 dev_info(dev, "probe failed (%d)\n", ret);
765
766 return ret;
767}
768
769static int usbhs_remove(struct platform_device *pdev)
770{
771 struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
772
773 dev_dbg(&pdev->dev, "usb remove\n");
774
775
776 if (!usbhs_get_dparam(priv, runtime_pwctrl))
777 usbhsc_power_ctrl(priv, 0);
778
779 pm_runtime_disable(&pdev->dev);
780
781 usbhs_platform_call(priv, hardware_exit, pdev);
782 usbhsc_clk_put(priv);
783 reset_control_assert(priv->rsts);
784 usbhs_mod_remove(priv);
785 usbhs_fifo_remove(priv);
786 usbhs_pipe_remove(priv);
787
788 return 0;
789}
790
791static __maybe_unused int usbhsc_suspend(struct device *dev)
792{
793 struct usbhs_priv *priv = dev_get_drvdata(dev);
794 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
795
796 if (mod) {
797 usbhs_mod_call(priv, stop, priv);
798 usbhs_mod_change(priv, -1);
799 }
800
801 if (mod || !usbhs_get_dparam(priv, runtime_pwctrl))
802 usbhsc_power_ctrl(priv, 0);
803
804 return 0;
805}
806
807static __maybe_unused int usbhsc_resume(struct device *dev)
808{
809 struct usbhs_priv *priv = dev_get_drvdata(dev);
810 struct platform_device *pdev = usbhs_priv_to_pdev(priv);
811
812 if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
813 usbhsc_power_ctrl(priv, 1);
814 usbhs_mod_autonomy_mode(priv);
815 }
816
817 usbhs_platform_call(priv, phy_reset, pdev);
818
819 usbhsc_schedule_notify_hotplug(pdev);
820
821 return 0;
822}
823
824static SIMPLE_DEV_PM_OPS(usbhsc_pm_ops, usbhsc_suspend, usbhsc_resume);
825
826static struct platform_driver renesas_usbhs_driver = {
827 .driver = {
828 .name = "renesas_usbhs",
829 .pm = &usbhsc_pm_ops,
830 .of_match_table = of_match_ptr(usbhs_of_match),
831 },
832 .probe = usbhs_probe,
833 .remove = usbhs_remove,
834};
835
836module_platform_driver(renesas_usbhs_driver);
837
838MODULE_LICENSE("GPL");
839MODULE_DESCRIPTION("Renesas USB driver");
840MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
841