xref: /kernel/linux/linux-5.10/drivers/usb/cdns3/core.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Cadence USBSS DRD Driver.
4 *
5 * Copyright (C) 2018-2019 Cadence.
6 * Copyright (C) 2017-2018 NXP
7 * Copyright (C) 2019 Texas Instruments
8 *
9 * Author: Peter Chen <peter.chen@nxp.com>
10 *         Pawel Laszczak <pawell@cadence.com>
11 *         Roger Quadros <rogerq@ti.com>
12 */
13
14#include <linux/dma-mapping.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/pm_runtime.h>
21
22#include "gadget.h"
23#include "core.h"
24#include "host-export.h"
25#include "gadget-export.h"
26#include "drd.h"
27
28static int cdns3_idle_init(struct cdns3 *cdns);
29
30static int cdns3_role_start(struct cdns3 *cdns, enum usb_role role)
31{
32	int ret;
33
34	if (WARN_ON(role > USB_ROLE_DEVICE))
35		return 0;
36
37	mutex_lock(&cdns->mutex);
38	cdns->role = role;
39	mutex_unlock(&cdns->mutex);
40
41	if (!cdns->roles[role])
42		return -ENXIO;
43
44	if (cdns->roles[role]->state == CDNS3_ROLE_STATE_ACTIVE)
45		return 0;
46
47	mutex_lock(&cdns->mutex);
48	ret = cdns->roles[role]->start(cdns);
49	if (!ret)
50		cdns->roles[role]->state = CDNS3_ROLE_STATE_ACTIVE;
51	mutex_unlock(&cdns->mutex);
52
53	return ret;
54}
55
56static void cdns3_role_stop(struct cdns3 *cdns)
57{
58	enum usb_role role = cdns->role;
59
60	if (WARN_ON(role > USB_ROLE_DEVICE))
61		return;
62
63	if (cdns->roles[role]->state == CDNS3_ROLE_STATE_INACTIVE)
64		return;
65
66	mutex_lock(&cdns->mutex);
67	cdns->roles[role]->stop(cdns);
68	cdns->roles[role]->state = CDNS3_ROLE_STATE_INACTIVE;
69	mutex_unlock(&cdns->mutex);
70}
71
72static void cdns3_exit_roles(struct cdns3 *cdns)
73{
74	cdns3_role_stop(cdns);
75	cdns3_drd_exit(cdns);
76}
77
78/**
79 * cdns3_core_init_role - initialize role of operation
80 * @cdns: Pointer to cdns3 structure
81 *
82 * Returns 0 on success otherwise negative errno
83 */
84static int cdns3_core_init_role(struct cdns3 *cdns)
85{
86	struct device *dev = cdns->dev;
87	enum usb_dr_mode best_dr_mode;
88	enum usb_dr_mode dr_mode;
89	int ret;
90
91	dr_mode = usb_get_dr_mode(dev);
92	cdns->role = USB_ROLE_NONE;
93
94	/*
95	 * If driver can't read mode by means of usb_get_dr_mode function then
96	 * chooses mode according with Kernel configuration. This setting
97	 * can be restricted later depending on strap pin configuration.
98	 */
99	if (dr_mode == USB_DR_MODE_UNKNOWN) {
100		if (cdns->version == CDNSP_CONTROLLER_V2) {
101			if (IS_ENABLED(CONFIG_USB_CDNSP_HOST) &&
102			    IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
103				dr_mode = USB_DR_MODE_OTG;
104			else if (IS_ENABLED(CONFIG_USB_CDNSP_HOST))
105				dr_mode = USB_DR_MODE_HOST;
106			else if (IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
107				dr_mode = USB_DR_MODE_PERIPHERAL;
108		} else {
109			if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
110			    IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
111				dr_mode = USB_DR_MODE_OTG;
112			else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
113				dr_mode = USB_DR_MODE_HOST;
114			else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
115				dr_mode = USB_DR_MODE_PERIPHERAL;
116		}
117	}
118
119	/*
120	 * At this point cdns->dr_mode contains strap configuration.
121	 * Driver try update this setting considering kernel configuration
122	 */
123	best_dr_mode = cdns->dr_mode;
124
125	ret = cdns3_idle_init(cdns);
126	if (ret)
127		return ret;
128
129	if (dr_mode == USB_DR_MODE_OTG) {
130		best_dr_mode = cdns->dr_mode;
131	} else if (cdns->dr_mode == USB_DR_MODE_OTG) {
132		best_dr_mode = dr_mode;
133	} else if (cdns->dr_mode != dr_mode) {
134		dev_err(dev, "Incorrect DRD configuration\n");
135		return -EINVAL;
136	}
137
138	dr_mode = best_dr_mode;
139
140	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
141		ret = cdns3_host_init(cdns);
142		if (ret) {
143			dev_err(dev, "Host initialization failed with %d\n",
144				ret);
145			goto err;
146		}
147	}
148
149	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
150		ret = cdns3_gadget_init(cdns);
151		if (ret) {
152			dev_err(dev, "Device initialization failed with %d\n",
153				ret);
154			goto err;
155		}
156	}
157
158	cdns->dr_mode = dr_mode;
159
160	ret = cdns3_drd_update_mode(cdns);
161	if (ret)
162		goto err;
163
164	/* Initialize idle role to start with */
165	ret = cdns3_role_start(cdns, USB_ROLE_NONE);
166	if (ret)
167		goto err;
168
169	switch (cdns->dr_mode) {
170	case USB_DR_MODE_OTG:
171		ret = cdns3_hw_role_switch(cdns);
172		if (ret)
173			goto err;
174		break;
175	case USB_DR_MODE_PERIPHERAL:
176		ret = cdns3_role_start(cdns, USB_ROLE_DEVICE);
177		if (ret)
178			goto err;
179		break;
180	case USB_DR_MODE_HOST:
181		ret = cdns3_role_start(cdns, USB_ROLE_HOST);
182		if (ret)
183			goto err;
184		break;
185	default:
186		ret = -EINVAL;
187		goto err;
188	}
189
190	return 0;
191err:
192	cdns3_exit_roles(cdns);
193	return ret;
194}
195
196/**
197 * cdns3_hw_role_state_machine  - role switch state machine based on hw events.
198 * @cdns: Pointer to controller structure.
199 *
200 * Returns next role to be entered based on hw events.
201 */
202static enum usb_role cdns3_hw_role_state_machine(struct cdns3 *cdns)
203{
204	enum usb_role role = USB_ROLE_NONE;
205	int id, vbus;
206
207	if (cdns->dr_mode != USB_DR_MODE_OTG) {
208		if (cdns3_is_host(cdns))
209			role = USB_ROLE_HOST;
210		if (cdns3_is_device(cdns))
211			role = USB_ROLE_DEVICE;
212
213		return role;
214	}
215
216	id = cdns3_get_id(cdns);
217	vbus = cdns3_get_vbus(cdns);
218
219	/*
220	 * Role change state machine
221	 * Inputs: ID, VBUS
222	 * Previous state: cdns->role
223	 * Next state: role
224	 */
225	role = cdns->role;
226
227	switch (role) {
228	case USB_ROLE_NONE:
229		/*
230		 * Driver treats USB_ROLE_NONE synonymous to IDLE state from
231		 * controller specification.
232		 */
233		if (!id)
234			role = USB_ROLE_HOST;
235		else if (vbus)
236			role = USB_ROLE_DEVICE;
237		break;
238	case USB_ROLE_HOST: /* from HOST, we can only change to NONE */
239		if (id)
240			role = USB_ROLE_NONE;
241		break;
242	case USB_ROLE_DEVICE: /* from GADGET, we can only change to NONE*/
243		if (!vbus)
244			role = USB_ROLE_NONE;
245		break;
246	}
247
248	dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role);
249
250	return role;
251}
252
253static int cdns3_idle_role_start(struct cdns3 *cdns)
254{
255	return 0;
256}
257
258static void cdns3_idle_role_stop(struct cdns3 *cdns)
259{
260	/* Program Lane swap and bring PHY out of RESET */
261	phy_reset(cdns->usb3_phy);
262}
263
264static int cdns3_idle_init(struct cdns3 *cdns)
265{
266	struct cdns3_role_driver *rdrv;
267
268	rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
269	if (!rdrv)
270		return -ENOMEM;
271
272	rdrv->start = cdns3_idle_role_start;
273	rdrv->stop = cdns3_idle_role_stop;
274	rdrv->state = CDNS3_ROLE_STATE_INACTIVE;
275	rdrv->suspend = NULL;
276	rdrv->resume = NULL;
277	rdrv->name = "idle";
278
279	cdns->roles[USB_ROLE_NONE] = rdrv;
280
281	return 0;
282}
283
284/**
285 * cdns3_hw_role_switch - switch roles based on HW state
286 * @cdns: controller
287 */
288int cdns3_hw_role_switch(struct cdns3 *cdns)
289{
290	enum usb_role real_role, current_role;
291	int ret = 0;
292
293	/* Depends on role switch class */
294	if (cdns->role_sw)
295		return 0;
296
297	pm_runtime_get_sync(cdns->dev);
298
299	current_role = cdns->role;
300	real_role = cdns3_hw_role_state_machine(cdns);
301
302	/* Do nothing if nothing changed */
303	if (current_role == real_role)
304		goto exit;
305
306	cdns3_role_stop(cdns);
307
308	dev_dbg(cdns->dev, "Switching role %d -> %d", current_role, real_role);
309
310	ret = cdns3_role_start(cdns, real_role);
311	if (ret) {
312		/* Back to current role */
313		dev_err(cdns->dev, "set %d has failed, back to %d\n",
314			real_role, current_role);
315		ret = cdns3_role_start(cdns, current_role);
316		if (ret)
317			dev_err(cdns->dev, "back to %d failed too\n",
318				current_role);
319	}
320exit:
321	pm_runtime_put_sync(cdns->dev);
322	return ret;
323}
324
325/**
326 * cdsn3_role_get - get current role of controller.
327 *
328 * @sw: pointer to USB role switch structure
329 *
330 * Returns role
331 */
332static enum usb_role cdns3_role_get(struct usb_role_switch *sw)
333{
334	struct cdns3 *cdns = usb_role_switch_get_drvdata(sw);
335
336	return cdns->role;
337}
338
339/**
340 * cdns3_role_set - set current role of controller.
341 *
342 * @sw: pointer to USB role switch structure
343 * @role: the previous role
344 * Handles below events:
345 * - Role switch for dual-role devices
346 * - USB_ROLE_GADGET <--> USB_ROLE_NONE for peripheral-only devices
347 */
348static int cdns3_role_set(struct usb_role_switch *sw, enum usb_role role)
349{
350	struct cdns3 *cdns = usb_role_switch_get_drvdata(sw);
351	int ret = 0;
352
353	pm_runtime_get_sync(cdns->dev);
354
355	if (cdns->role == role)
356		goto pm_put;
357
358	if (cdns->dr_mode == USB_DR_MODE_HOST) {
359		switch (role) {
360		case USB_ROLE_NONE:
361		case USB_ROLE_HOST:
362			break;
363		default:
364			goto pm_put;
365		}
366	}
367
368	if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) {
369		switch (role) {
370		case USB_ROLE_NONE:
371		case USB_ROLE_DEVICE:
372			break;
373		default:
374			goto pm_put;
375		}
376	}
377
378	cdns3_role_stop(cdns);
379	ret = cdns3_role_start(cdns, role);
380	if (ret)
381		dev_err(cdns->dev, "set role %d has failed\n", role);
382
383pm_put:
384	pm_runtime_put_sync(cdns->dev);
385	return ret;
386}
387
388static int set_phy_power_on(struct cdns3 *cdns)
389{
390	int ret;
391
392	ret = phy_power_on(cdns->usb2_phy);
393	if (ret)
394		return ret;
395
396	ret = phy_power_on(cdns->usb3_phy);
397	if (ret)
398		phy_power_off(cdns->usb2_phy);
399
400	return ret;
401}
402
403static void set_phy_power_off(struct cdns3 *cdns)
404{
405	phy_power_off(cdns->usb3_phy);
406	phy_power_off(cdns->usb2_phy);
407}
408
409/**
410 * cdns3_wakeup_irq - interrupt handler for wakeup events
411 * @irq: irq number for cdns3 core device
412 * @data: structure of cdns3
413 *
414 * Returns IRQ_HANDLED or IRQ_NONE
415 */
416static irqreturn_t cdns3_wakeup_irq(int irq, void *data)
417{
418	struct cdns3 *cdns = data;
419
420	if (cdns->in_lpm) {
421		disable_irq_nosync(irq);
422		cdns->wakeup_pending = true;
423		if ((cdns->role == USB_ROLE_HOST) && cdns->host_dev)
424			pm_request_resume(&cdns->host_dev->dev);
425
426		return IRQ_HANDLED;
427	}
428
429	return IRQ_NONE;
430}
431
432/**
433 * cdns3_probe - probe for cdns3 core device
434 * @pdev: Pointer to cdns3 core platform device
435 *
436 * Returns 0 on success otherwise negative errno
437 */
438static int cdns3_probe(struct platform_device *pdev)
439{
440	struct device *dev = &pdev->dev;
441	struct resource	*res;
442	struct cdns3 *cdns;
443	void __iomem *regs;
444	int ret;
445
446	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
447	if (ret) {
448		dev_err(dev, "error setting dma mask: %d\n", ret);
449		return ret;
450	}
451
452	cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
453	if (!cdns)
454		return -ENOMEM;
455
456	cdns->dev = dev;
457	cdns->pdata = dev_get_platdata(dev);
458
459	platform_set_drvdata(pdev, cdns);
460
461	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "host");
462	if (!res) {
463		dev_err(dev, "missing host IRQ\n");
464		return -ENODEV;
465	}
466
467	cdns->xhci_res[0] = *res;
468
469	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xhci");
470	if (!res) {
471		dev_err(dev, "couldn't get xhci resource\n");
472		return -ENXIO;
473	}
474
475	cdns->xhci_res[1] = *res;
476
477	cdns->dev_irq = platform_get_irq_byname(pdev, "peripheral");
478	if (cdns->dev_irq == -EPROBE_DEFER)
479		return cdns->dev_irq;
480
481	if (cdns->dev_irq < 0)
482		dev_err(dev, "couldn't get peripheral irq\n");
483
484	regs = devm_platform_ioremap_resource_byname(pdev, "dev");
485	if (IS_ERR(regs))
486		return PTR_ERR(regs);
487	cdns->dev_regs	= regs;
488
489	cdns->otg_irq = platform_get_irq_byname(pdev, "otg");
490	if (cdns->otg_irq == -EPROBE_DEFER)
491		return cdns->otg_irq;
492
493	if (cdns->otg_irq < 0) {
494		dev_err(dev, "couldn't get otg irq\n");
495		return cdns->otg_irq;
496	}
497
498	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otg");
499	if (!res) {
500		dev_err(dev, "couldn't get otg resource\n");
501		return -ENXIO;
502	}
503
504	cdns->phyrst_a_enable = device_property_read_bool(dev, "cdns,phyrst-a-enable");
505
506	cdns->otg_res = *res;
507
508	cdns->wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup");
509	if (cdns->wakeup_irq == -EPROBE_DEFER)
510		return cdns->wakeup_irq;
511	else if (cdns->wakeup_irq == 0)
512		return -EINVAL;
513
514	if (cdns->wakeup_irq < 0) {
515		dev_dbg(dev, "couldn't get wakeup irq\n");
516		cdns->wakeup_irq = 0x0;
517	}
518
519	mutex_init(&cdns->mutex);
520
521	cdns->usb2_phy = devm_phy_optional_get(dev, "cdns3,usb2-phy");
522	if (IS_ERR(cdns->usb2_phy))
523		return PTR_ERR(cdns->usb2_phy);
524
525	ret = phy_init(cdns->usb2_phy);
526	if (ret)
527		return ret;
528
529	cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy");
530	if (IS_ERR(cdns->usb3_phy))
531		return PTR_ERR(cdns->usb3_phy);
532
533	ret = phy_init(cdns->usb3_phy);
534	if (ret)
535		goto err1;
536
537	ret = set_phy_power_on(cdns);
538	if (ret)
539		goto err2;
540
541	if (device_property_read_bool(dev, "usb-role-switch")) {
542		struct usb_role_switch_desc sw_desc = { };
543
544		sw_desc.set = cdns3_role_set;
545		sw_desc.get = cdns3_role_get;
546		sw_desc.allow_userspace_control = true;
547		sw_desc.driver_data = cdns;
548		sw_desc.fwnode = dev->fwnode;
549
550		cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
551		if (IS_ERR(cdns->role_sw)) {
552			ret = PTR_ERR(cdns->role_sw);
553			dev_warn(dev, "Unable to register Role Switch\n");
554			goto err3;
555		}
556	}
557
558	if (cdns->wakeup_irq) {
559		ret = devm_request_irq(cdns->dev, cdns->wakeup_irq,
560						cdns3_wakeup_irq,
561						IRQF_SHARED,
562						dev_name(cdns->dev), cdns);
563
564		if (ret) {
565			dev_err(cdns->dev, "couldn't register wakeup irq handler\n");
566			goto err4;
567		}
568	}
569
570	ret = cdns3_drd_init(cdns);
571	if (ret)
572		goto err4;
573
574	ret = cdns3_core_init_role(cdns);
575	if (ret)
576		goto err4;
577
578	spin_lock_init(&cdns->lock);
579	device_set_wakeup_capable(dev, true);
580	pm_runtime_set_active(dev);
581	pm_runtime_enable(dev);
582	if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)))
583		pm_runtime_forbid(dev);
584
585	/*
586	 * The controller needs less time between bus and controller suspend,
587	 * and we also needs a small delay to avoid frequently entering low
588	 * power mode.
589	 */
590	pm_runtime_set_autosuspend_delay(dev, 20);
591	pm_runtime_mark_last_busy(dev);
592	pm_runtime_use_autosuspend(dev);
593	dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
594
595	return 0;
596err4:
597	cdns3_drd_exit(cdns);
598	if (cdns->role_sw)
599		usb_role_switch_unregister(cdns->role_sw);
600err3:
601	set_phy_power_off(cdns);
602err2:
603	phy_exit(cdns->usb3_phy);
604err1:
605	phy_exit(cdns->usb2_phy);
606
607	return ret;
608}
609
610/**
611 * cdns3_remove - unbind drd driver and clean up
612 * @pdev: Pointer to Linux platform device
613 *
614 * Returns 0 on success otherwise negative errno
615 */
616static int cdns3_remove(struct platform_device *pdev)
617{
618	struct cdns3 *cdns = platform_get_drvdata(pdev);
619
620	pm_runtime_get_sync(&pdev->dev);
621	pm_runtime_disable(&pdev->dev);
622	pm_runtime_put_noidle(&pdev->dev);
623	cdns3_exit_roles(cdns);
624	usb_role_switch_unregister(cdns->role_sw);
625	set_phy_power_off(cdns);
626	phy_exit(cdns->usb2_phy);
627	phy_exit(cdns->usb3_phy);
628	return 0;
629}
630
631#ifdef CONFIG_PM
632
633static int cdns3_set_platform_suspend(struct device *dev,
634		bool suspend, bool wakeup)
635{
636	struct cdns3 *cdns = dev_get_drvdata(dev);
637	int ret = 0;
638
639	if (cdns->pdata && cdns->pdata->platform_suspend)
640		ret = cdns->pdata->platform_suspend(dev, suspend, wakeup);
641
642	return ret;
643}
644
645static int cdns3_controller_suspend(struct device *dev, pm_message_t msg)
646{
647	struct cdns3 *cdns = dev_get_drvdata(dev);
648	bool wakeup;
649	unsigned long flags;
650
651	if (cdns->in_lpm)
652		return 0;
653
654	if (PMSG_IS_AUTO(msg))
655		wakeup = true;
656	else
657		wakeup = device_may_wakeup(dev);
658
659	cdns3_set_platform_suspend(cdns->dev, true, wakeup);
660	set_phy_power_off(cdns);
661	spin_lock_irqsave(&cdns->lock, flags);
662	cdns->in_lpm = true;
663	spin_unlock_irqrestore(&cdns->lock, flags);
664	dev_dbg(cdns->dev, "%s ends\n", __func__);
665
666	return 0;
667}
668
669static int cdns3_controller_resume(struct device *dev, pm_message_t msg)
670{
671	struct cdns3 *cdns = dev_get_drvdata(dev);
672	int ret;
673	unsigned long flags;
674
675	if (!cdns->in_lpm)
676		return 0;
677
678	ret = set_phy_power_on(cdns);
679	if (ret)
680		return ret;
681
682	cdns3_set_platform_suspend(cdns->dev, false, false);
683
684	spin_lock_irqsave(&cdns->lock, flags);
685	if (cdns->roles[cdns->role]->resume && !PMSG_IS_AUTO(msg))
686		cdns->roles[cdns->role]->resume(cdns, false);
687
688	cdns->in_lpm = false;
689	spin_unlock_irqrestore(&cdns->lock, flags);
690	if (cdns->wakeup_pending) {
691		cdns->wakeup_pending = false;
692		enable_irq(cdns->wakeup_irq);
693	}
694	dev_dbg(cdns->dev, "%s ends\n", __func__);
695
696	return ret;
697}
698
699static int cdns3_runtime_suspend(struct device *dev)
700{
701	return cdns3_controller_suspend(dev, PMSG_AUTO_SUSPEND);
702}
703
704static int cdns3_runtime_resume(struct device *dev)
705{
706	return cdns3_controller_resume(dev, PMSG_AUTO_RESUME);
707}
708#ifdef CONFIG_PM_SLEEP
709
710static int cdns3_suspend(struct device *dev)
711{
712	struct cdns3 *cdns = dev_get_drvdata(dev);
713	unsigned long flags;
714
715	if (pm_runtime_status_suspended(dev))
716		pm_runtime_resume(dev);
717
718	if (cdns->roles[cdns->role]->suspend) {
719		spin_lock_irqsave(&cdns->lock, flags);
720		cdns->roles[cdns->role]->suspend(cdns, false);
721		spin_unlock_irqrestore(&cdns->lock, flags);
722	}
723
724	return cdns3_controller_suspend(dev, PMSG_SUSPEND);
725}
726
727static int cdns3_resume(struct device *dev)
728{
729	int ret;
730
731	ret = cdns3_controller_resume(dev, PMSG_RESUME);
732	if (ret)
733		return ret;
734
735	pm_runtime_disable(dev);
736	pm_runtime_set_active(dev);
737	pm_runtime_enable(dev);
738
739	return ret;
740}
741#endif /* CONFIG_PM_SLEEP */
742#endif /* CONFIG_PM */
743
744static const struct dev_pm_ops cdns3_pm_ops = {
745	SET_SYSTEM_SLEEP_PM_OPS(cdns3_suspend, cdns3_resume)
746	SET_RUNTIME_PM_OPS(cdns3_runtime_suspend, cdns3_runtime_resume, NULL)
747};
748
749#ifdef CONFIG_OF
750static const struct of_device_id of_cdns3_match[] = {
751	{ .compatible = "cdns,usb3" },
752	{ },
753};
754MODULE_DEVICE_TABLE(of, of_cdns3_match);
755#endif
756
757static struct platform_driver cdns3_driver = {
758	.probe		= cdns3_probe,
759	.remove		= cdns3_remove,
760	.driver		= {
761		.name	= "cdns-usb3",
762		.of_match_table	= of_match_ptr(of_cdns3_match),
763		.pm	= &cdns3_pm_ops,
764	},
765};
766
767module_platform_driver(cdns3_driver);
768
769MODULE_ALIAS("platform:cdns3");
770MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
771MODULE_LICENSE("GPL v2");
772MODULE_DESCRIPTION("Cadence USB3 DRD Controller Driver");
773