xref: /OK3568_Linux_fs/kernel/drivers/usb/musb/ux500.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2010 ST-Ericsson AB
4*4882a593Smuzhiyun  * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Based on omap2430.c
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/clk.h>
12*4882a593Smuzhiyun #include <linux/err.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <linux/of.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/usb/musb-ux500.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "musb_core.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun static const struct musb_hdrc_config ux500_musb_hdrc_config = {
21*4882a593Smuzhiyun 	.multipoint	= true,
22*4882a593Smuzhiyun 	.dyn_fifo	= true,
23*4882a593Smuzhiyun 	.num_eps	= 16,
24*4882a593Smuzhiyun 	.ram_bits	= 16,
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun struct ux500_glue {
28*4882a593Smuzhiyun 	struct device		*dev;
29*4882a593Smuzhiyun 	struct platform_device	*musb;
30*4882a593Smuzhiyun 	struct clk		*clk;
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun #define glue_to_musb(g)	platform_get_drvdata(g->musb)
33*4882a593Smuzhiyun 
ux500_musb_set_vbus(struct musb * musb,int is_on)34*4882a593Smuzhiyun static void ux500_musb_set_vbus(struct musb *musb, int is_on)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	u8            devctl;
37*4882a593Smuzhiyun 	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
38*4882a593Smuzhiyun 	/* HDRC controls CPEN, but beware current surges during device
39*4882a593Smuzhiyun 	 * connect.  They can trigger transient overcurrent conditions
40*4882a593Smuzhiyun 	 * that must be ignored.
41*4882a593Smuzhiyun 	 */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	if (is_on) {
46*4882a593Smuzhiyun 		if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) {
47*4882a593Smuzhiyun 			/* start the session */
48*4882a593Smuzhiyun 			devctl |= MUSB_DEVCTL_SESSION;
49*4882a593Smuzhiyun 			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
50*4882a593Smuzhiyun 			/*
51*4882a593Smuzhiyun 			 * Wait for the musb to set as A device to enable the
52*4882a593Smuzhiyun 			 * VBUS
53*4882a593Smuzhiyun 			 */
54*4882a593Smuzhiyun 			while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 				if (time_after(jiffies, timeout)) {
57*4882a593Smuzhiyun 					dev_err(musb->controller,
58*4882a593Smuzhiyun 					"configured as A device timeout");
59*4882a593Smuzhiyun 					break;
60*4882a593Smuzhiyun 				}
61*4882a593Smuzhiyun 			}
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 		} else {
64*4882a593Smuzhiyun 			musb->is_active = 1;
65*4882a593Smuzhiyun 			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
66*4882a593Smuzhiyun 			devctl |= MUSB_DEVCTL_SESSION;
67*4882a593Smuzhiyun 			MUSB_HST_MODE(musb);
68*4882a593Smuzhiyun 		}
69*4882a593Smuzhiyun 	} else {
70*4882a593Smuzhiyun 		musb->is_active = 0;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 		/* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and jumping
73*4882a593Smuzhiyun 		 * right to B_IDLE...
74*4882a593Smuzhiyun 		 */
75*4882a593Smuzhiyun 		devctl &= ~MUSB_DEVCTL_SESSION;
76*4882a593Smuzhiyun 		MUSB_DEV_MODE(musb);
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun 	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	/*
81*4882a593Smuzhiyun 	 * Devctl values will be updated after vbus goes below
82*4882a593Smuzhiyun 	 * session_valid. The time taken depends on the capacitance
83*4882a593Smuzhiyun 	 * on VBUS line. The max discharge time can be upto 1 sec
84*4882a593Smuzhiyun 	 * as per the spec. Typically on our platform, it is 200ms
85*4882a593Smuzhiyun 	 */
86*4882a593Smuzhiyun 	if (!is_on)
87*4882a593Smuzhiyun 		mdelay(200);
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
90*4882a593Smuzhiyun 		usb_otg_state_string(musb->xceiv->otg->state),
91*4882a593Smuzhiyun 		musb_readb(musb->mregs, MUSB_DEVCTL));
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
musb_otg_notifications(struct notifier_block * nb,unsigned long event,void * unused)94*4882a593Smuzhiyun static int musb_otg_notifications(struct notifier_block *nb,
95*4882a593Smuzhiyun 		unsigned long event, void *unused)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	struct musb *musb = container_of(nb, struct musb, nb);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	dev_dbg(musb->controller, "musb_otg_notifications %ld %s\n",
100*4882a593Smuzhiyun 			event, usb_otg_state_string(musb->xceiv->otg->state));
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	switch (event) {
103*4882a593Smuzhiyun 	case UX500_MUSB_ID:
104*4882a593Smuzhiyun 		dev_dbg(musb->controller, "ID GND\n");
105*4882a593Smuzhiyun 		ux500_musb_set_vbus(musb, 1);
106*4882a593Smuzhiyun 		break;
107*4882a593Smuzhiyun 	case UX500_MUSB_VBUS:
108*4882a593Smuzhiyun 		dev_dbg(musb->controller, "VBUS Connect\n");
109*4882a593Smuzhiyun 		break;
110*4882a593Smuzhiyun 	case UX500_MUSB_NONE:
111*4882a593Smuzhiyun 		dev_dbg(musb->controller, "VBUS Disconnect\n");
112*4882a593Smuzhiyun 		if (is_host_active(musb))
113*4882a593Smuzhiyun 			ux500_musb_set_vbus(musb, 0);
114*4882a593Smuzhiyun 		else
115*4882a593Smuzhiyun 			musb->xceiv->otg->state = OTG_STATE_B_IDLE;
116*4882a593Smuzhiyun 		break;
117*4882a593Smuzhiyun 	default:
118*4882a593Smuzhiyun 		dev_dbg(musb->controller, "ID float\n");
119*4882a593Smuzhiyun 		return NOTIFY_DONE;
120*4882a593Smuzhiyun 	}
121*4882a593Smuzhiyun 	return NOTIFY_OK;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun 
ux500_musb_interrupt(int irq,void * __hci)124*4882a593Smuzhiyun static irqreturn_t ux500_musb_interrupt(int irq, void *__hci)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	unsigned long   flags;
127*4882a593Smuzhiyun 	irqreturn_t     retval = IRQ_NONE;
128*4882a593Smuzhiyun 	struct musb     *musb = __hci;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	spin_lock_irqsave(&musb->lock, flags);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
133*4882a593Smuzhiyun 	musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
134*4882a593Smuzhiyun 	musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	if (musb->int_usb || musb->int_tx || musb->int_rx)
137*4882a593Smuzhiyun 		retval = musb_interrupt(musb);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	spin_unlock_irqrestore(&musb->lock, flags);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	return retval;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
ux500_musb_init(struct musb * musb)144*4882a593Smuzhiyun static int ux500_musb_init(struct musb *musb)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun 	int status;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
149*4882a593Smuzhiyun 	if (IS_ERR_OR_NULL(musb->xceiv)) {
150*4882a593Smuzhiyun 		pr_err("HS USB OTG: no transceiver configured\n");
151*4882a593Smuzhiyun 		return -EPROBE_DEFER;
152*4882a593Smuzhiyun 	}
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	musb->nb.notifier_call = musb_otg_notifications;
155*4882a593Smuzhiyun 	status = usb_register_notifier(musb->xceiv, &musb->nb);
156*4882a593Smuzhiyun 	if (status < 0) {
157*4882a593Smuzhiyun 		dev_dbg(musb->controller, "notification register failed\n");
158*4882a593Smuzhiyun 		return status;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	musb->isr = ux500_musb_interrupt;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
ux500_musb_exit(struct musb * musb)166*4882a593Smuzhiyun static int ux500_musb_exit(struct musb *musb)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	usb_unregister_notifier(musb->xceiv, &musb->nb);
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	usb_put_phy(musb->xceiv);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	return 0;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun static const struct musb_platform_ops ux500_ops = {
176*4882a593Smuzhiyun 	.quirks		= MUSB_DMA_UX500 | MUSB_INDEXED_EP,
177*4882a593Smuzhiyun #ifdef CONFIG_USB_UX500_DMA
178*4882a593Smuzhiyun 	.dma_init	= ux500_dma_controller_create,
179*4882a593Smuzhiyun 	.dma_exit	= ux500_dma_controller_destroy,
180*4882a593Smuzhiyun #endif
181*4882a593Smuzhiyun 	.init		= ux500_musb_init,
182*4882a593Smuzhiyun 	.exit		= ux500_musb_exit,
183*4882a593Smuzhiyun 	.fifo_mode	= 5,
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	.set_vbus	= ux500_musb_set_vbus,
186*4882a593Smuzhiyun };
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun static struct musb_hdrc_platform_data *
ux500_of_probe(struct platform_device * pdev,struct device_node * np)189*4882a593Smuzhiyun ux500_of_probe(struct platform_device *pdev, struct device_node *np)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	struct musb_hdrc_platform_data *pdata;
192*4882a593Smuzhiyun 	const char *mode;
193*4882a593Smuzhiyun 	int strlen;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
196*4882a593Smuzhiyun 	if (!pdata)
197*4882a593Smuzhiyun 		return NULL;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	mode = of_get_property(np, "dr_mode", &strlen);
200*4882a593Smuzhiyun 	if (!mode) {
201*4882a593Smuzhiyun 		dev_err(&pdev->dev, "No 'dr_mode' property found\n");
202*4882a593Smuzhiyun 		return NULL;
203*4882a593Smuzhiyun 	}
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	if (strlen > 0) {
206*4882a593Smuzhiyun 		if (!strcmp(mode, "host"))
207*4882a593Smuzhiyun 			pdata->mode = MUSB_HOST;
208*4882a593Smuzhiyun 		if (!strcmp(mode, "otg"))
209*4882a593Smuzhiyun 			pdata->mode = MUSB_OTG;
210*4882a593Smuzhiyun 		if (!strcmp(mode, "peripheral"))
211*4882a593Smuzhiyun 			pdata->mode = MUSB_PERIPHERAL;
212*4882a593Smuzhiyun 	}
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	return pdata;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun 
ux500_probe(struct platform_device * pdev)217*4882a593Smuzhiyun static int ux500_probe(struct platform_device *pdev)
218*4882a593Smuzhiyun {
219*4882a593Smuzhiyun 	struct resource musb_resources[2];
220*4882a593Smuzhiyun 	struct musb_hdrc_platform_data	*pdata = dev_get_platdata(&pdev->dev);
221*4882a593Smuzhiyun 	struct device_node		*np = pdev->dev.of_node;
222*4882a593Smuzhiyun 	struct platform_device		*musb;
223*4882a593Smuzhiyun 	struct ux500_glue		*glue;
224*4882a593Smuzhiyun 	struct clk			*clk;
225*4882a593Smuzhiyun 	int				ret = -ENOMEM;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	if (!pdata) {
228*4882a593Smuzhiyun 		if (np) {
229*4882a593Smuzhiyun 			pdata = ux500_of_probe(pdev, np);
230*4882a593Smuzhiyun 			if (!pdata)
231*4882a593Smuzhiyun 				goto err0;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 			pdev->dev.platform_data = pdata;
234*4882a593Smuzhiyun 		} else {
235*4882a593Smuzhiyun 			dev_err(&pdev->dev, "no pdata or device tree found\n");
236*4882a593Smuzhiyun 			goto err0;
237*4882a593Smuzhiyun 		}
238*4882a593Smuzhiyun 	}
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
241*4882a593Smuzhiyun 	if (!glue)
242*4882a593Smuzhiyun 		goto err0;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
245*4882a593Smuzhiyun 	if (!musb) {
246*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to allocate musb device\n");
247*4882a593Smuzhiyun 		goto err0;
248*4882a593Smuzhiyun 	}
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	clk = devm_clk_get(&pdev->dev, NULL);
251*4882a593Smuzhiyun 	if (IS_ERR(clk)) {
252*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to get clock\n");
253*4882a593Smuzhiyun 		ret = PTR_ERR(clk);
254*4882a593Smuzhiyun 		goto err1;
255*4882a593Smuzhiyun 	}
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	ret = clk_prepare_enable(clk);
258*4882a593Smuzhiyun 	if (ret) {
259*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to enable clock\n");
260*4882a593Smuzhiyun 		goto err1;
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	musb->dev.parent		= &pdev->dev;
264*4882a593Smuzhiyun 	musb->dev.dma_mask		= &pdev->dev.coherent_dma_mask;
265*4882a593Smuzhiyun 	musb->dev.coherent_dma_mask	= pdev->dev.coherent_dma_mask;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	glue->dev			= &pdev->dev;
268*4882a593Smuzhiyun 	glue->musb			= musb;
269*4882a593Smuzhiyun 	glue->clk			= clk;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	pdata->platform_ops		= &ux500_ops;
272*4882a593Smuzhiyun 	pdata->config 			= &ux500_musb_hdrc_config;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	platform_set_drvdata(pdev, glue);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	memset(musb_resources, 0x00, sizeof(*musb_resources) *
277*4882a593Smuzhiyun 			ARRAY_SIZE(musb_resources));
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	musb_resources[0].name = pdev->resource[0].name;
280*4882a593Smuzhiyun 	musb_resources[0].start = pdev->resource[0].start;
281*4882a593Smuzhiyun 	musb_resources[0].end = pdev->resource[0].end;
282*4882a593Smuzhiyun 	musb_resources[0].flags = pdev->resource[0].flags;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	musb_resources[1].name = pdev->resource[1].name;
285*4882a593Smuzhiyun 	musb_resources[1].start = pdev->resource[1].start;
286*4882a593Smuzhiyun 	musb_resources[1].end = pdev->resource[1].end;
287*4882a593Smuzhiyun 	musb_resources[1].flags = pdev->resource[1].flags;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	ret = platform_device_add_resources(musb, musb_resources,
290*4882a593Smuzhiyun 			ARRAY_SIZE(musb_resources));
291*4882a593Smuzhiyun 	if (ret) {
292*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to add resources\n");
293*4882a593Smuzhiyun 		goto err2;
294*4882a593Smuzhiyun 	}
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
297*4882a593Smuzhiyun 	if (ret) {
298*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to add platform_data\n");
299*4882a593Smuzhiyun 		goto err2;
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	ret = platform_device_add(musb);
303*4882a593Smuzhiyun 	if (ret) {
304*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to register musb device\n");
305*4882a593Smuzhiyun 		goto err2;
306*4882a593Smuzhiyun 	}
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	return 0;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun err2:
311*4882a593Smuzhiyun 	clk_disable_unprepare(clk);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun err1:
314*4882a593Smuzhiyun 	platform_device_put(musb);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun err0:
317*4882a593Smuzhiyun 	return ret;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
ux500_remove(struct platform_device * pdev)320*4882a593Smuzhiyun static int ux500_remove(struct platform_device *pdev)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	struct ux500_glue	*glue = platform_get_drvdata(pdev);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	platform_device_unregister(glue->musb);
325*4882a593Smuzhiyun 	clk_disable_unprepare(glue->clk);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	return 0;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
ux500_suspend(struct device * dev)331*4882a593Smuzhiyun static int ux500_suspend(struct device *dev)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun 	struct ux500_glue	*glue = dev_get_drvdata(dev);
334*4882a593Smuzhiyun 	struct musb		*musb = glue_to_musb(glue);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	if (musb)
337*4882a593Smuzhiyun 		usb_phy_set_suspend(musb->xceiv, 1);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	clk_disable_unprepare(glue->clk);
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	return 0;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
ux500_resume(struct device * dev)344*4882a593Smuzhiyun static int ux500_resume(struct device *dev)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun 	struct ux500_glue	*glue = dev_get_drvdata(dev);
347*4882a593Smuzhiyun 	struct musb		*musb = glue_to_musb(glue);
348*4882a593Smuzhiyun 	int			ret;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	ret = clk_prepare_enable(glue->clk);
351*4882a593Smuzhiyun 	if (ret) {
352*4882a593Smuzhiyun 		dev_err(dev, "failed to enable clock\n");
353*4882a593Smuzhiyun 		return ret;
354*4882a593Smuzhiyun 	}
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (musb)
357*4882a593Smuzhiyun 		usb_phy_set_suspend(musb->xceiv, 0);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	return 0;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun #endif
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume);
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun static const struct of_device_id ux500_match[] = {
366*4882a593Smuzhiyun         { .compatible = "stericsson,db8500-musb", },
367*4882a593Smuzhiyun         {}
368*4882a593Smuzhiyun };
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, ux500_match);
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun static struct platform_driver ux500_driver = {
373*4882a593Smuzhiyun 	.probe		= ux500_probe,
374*4882a593Smuzhiyun 	.remove		= ux500_remove,
375*4882a593Smuzhiyun 	.driver		= {
376*4882a593Smuzhiyun 		.name	= "musb-ux500",
377*4882a593Smuzhiyun 		.pm	= &ux500_pm_ops,
378*4882a593Smuzhiyun 		.of_match_table = ux500_match,
379*4882a593Smuzhiyun 	},
380*4882a593Smuzhiyun };
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun MODULE_DESCRIPTION("UX500 MUSB Glue Layer");
383*4882a593Smuzhiyun MODULE_AUTHOR("Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>");
384*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
385*4882a593Smuzhiyun module_platform_driver(ux500_driver);
386