xref: /openbmc/linux/drivers/usb/musb/ux500.c (revision 09fc7d22)
14bc36fd3SMian Yousaf Kaukab /*
24bc36fd3SMian Yousaf Kaukab  * Copyright (C) 2010 ST-Ericsson AB
34bc36fd3SMian Yousaf Kaukab  * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
44bc36fd3SMian Yousaf Kaukab  *
54bc36fd3SMian Yousaf Kaukab  * Based on omap2430.c
64bc36fd3SMian Yousaf Kaukab  *
74bc36fd3SMian Yousaf Kaukab  * This program is free software; you can redistribute it and/or modify
84bc36fd3SMian Yousaf Kaukab  * it under the terms of the GNU General Public License as published by
94bc36fd3SMian Yousaf Kaukab  * the Free Software Foundation; either version 2 of the License, or
104bc36fd3SMian Yousaf Kaukab  * (at your option) any later version.
114bc36fd3SMian Yousaf Kaukab  *
124bc36fd3SMian Yousaf Kaukab  * This program is distributed in the hope that it will be useful,
134bc36fd3SMian Yousaf Kaukab  * but WITHOUT ANY WARRANTY; without even the implied warranty of
144bc36fd3SMian Yousaf Kaukab  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
154bc36fd3SMian Yousaf Kaukab  * GNU General Public License for more details.
164bc36fd3SMian Yousaf Kaukab  *
174bc36fd3SMian Yousaf Kaukab  * You should have received a copy of the GNU General Public License
184bc36fd3SMian Yousaf Kaukab  * along with this program; if not, write to the Free Software
194bc36fd3SMian Yousaf Kaukab  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
204bc36fd3SMian Yousaf Kaukab  */
214bc36fd3SMian Yousaf Kaukab 
224bc36fd3SMian Yousaf Kaukab #include <linux/module.h>
234bc36fd3SMian Yousaf Kaukab #include <linux/kernel.h>
244bc36fd3SMian Yousaf Kaukab #include <linux/init.h>
254bc36fd3SMian Yousaf Kaukab #include <linux/clk.h>
26ded017eeSKishon Vijay Abraham I #include <linux/err.h>
274bc36fd3SMian Yousaf Kaukab #include <linux/io.h>
284bc36fd3SMian Yousaf Kaukab #include <linux/platform_device.h>
29af6882beSFabio Baltieri #include <linux/usb/musb-ux500.h>
304bc36fd3SMian Yousaf Kaukab 
314bc36fd3SMian Yousaf Kaukab #include "musb_core.h"
324bc36fd3SMian Yousaf Kaukab 
334bc36fd3SMian Yousaf Kaukab struct ux500_glue {
344bc36fd3SMian Yousaf Kaukab 	struct device		*dev;
354bc36fd3SMian Yousaf Kaukab 	struct platform_device	*musb;
364bc36fd3SMian Yousaf Kaukab 	struct clk		*clk;
374bc36fd3SMian Yousaf Kaukab };
384bc36fd3SMian Yousaf Kaukab #define glue_to_musb(g)	platform_get_drvdata(g->musb)
394bc36fd3SMian Yousaf Kaukab 
40996a9d26SFabio Baltieri static void ux500_musb_set_vbus(struct musb *musb, int is_on)
41996a9d26SFabio Baltieri {
42996a9d26SFabio Baltieri 	u8            devctl;
43996a9d26SFabio Baltieri 	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
44996a9d26SFabio Baltieri 	/* HDRC controls CPEN, but beware current surges during device
45996a9d26SFabio Baltieri 	 * connect.  They can trigger transient overcurrent conditions
46996a9d26SFabio Baltieri 	 * that must be ignored.
47996a9d26SFabio Baltieri 	 */
48996a9d26SFabio Baltieri 
49996a9d26SFabio Baltieri 	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
50996a9d26SFabio Baltieri 
51996a9d26SFabio Baltieri 	if (is_on) {
52996a9d26SFabio Baltieri 		if (musb->xceiv->state == OTG_STATE_A_IDLE) {
53996a9d26SFabio Baltieri 			/* start the session */
54996a9d26SFabio Baltieri 			devctl |= MUSB_DEVCTL_SESSION;
55996a9d26SFabio Baltieri 			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
56996a9d26SFabio Baltieri 			/*
57996a9d26SFabio Baltieri 			 * Wait for the musb to set as A device to enable the
58996a9d26SFabio Baltieri 			 * VBUS
59996a9d26SFabio Baltieri 			 */
60996a9d26SFabio Baltieri 			while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
61996a9d26SFabio Baltieri 
62996a9d26SFabio Baltieri 				if (time_after(jiffies, timeout)) {
63996a9d26SFabio Baltieri 					dev_err(musb->controller,
64996a9d26SFabio Baltieri 					"configured as A device timeout");
65996a9d26SFabio Baltieri 					break;
66996a9d26SFabio Baltieri 				}
67996a9d26SFabio Baltieri 			}
68996a9d26SFabio Baltieri 
69996a9d26SFabio Baltieri 		} else {
70996a9d26SFabio Baltieri 			musb->is_active = 1;
71996a9d26SFabio Baltieri 			musb->xceiv->otg->default_a = 1;
72996a9d26SFabio Baltieri 			musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
73996a9d26SFabio Baltieri 			devctl |= MUSB_DEVCTL_SESSION;
74996a9d26SFabio Baltieri 			MUSB_HST_MODE(musb);
75996a9d26SFabio Baltieri 		}
76996a9d26SFabio Baltieri 	} else {
77996a9d26SFabio Baltieri 		musb->is_active = 0;
78996a9d26SFabio Baltieri 
79996a9d26SFabio Baltieri 		/* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and jumping
80996a9d26SFabio Baltieri 		 * right to B_IDLE...
81996a9d26SFabio Baltieri 		 */
82996a9d26SFabio Baltieri 		musb->xceiv->otg->default_a = 0;
83996a9d26SFabio Baltieri 		devctl &= ~MUSB_DEVCTL_SESSION;
84996a9d26SFabio Baltieri 		MUSB_DEV_MODE(musb);
85996a9d26SFabio Baltieri 	}
86996a9d26SFabio Baltieri 	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
87996a9d26SFabio Baltieri 
88996a9d26SFabio Baltieri 	/*
89996a9d26SFabio Baltieri 	 * Devctl values will be updated after vbus goes below
90996a9d26SFabio Baltieri 	 * session_valid. The time taken depends on the capacitance
91996a9d26SFabio Baltieri 	 * on VBUS line. The max discharge time can be upto 1 sec
92996a9d26SFabio Baltieri 	 * as per the spec. Typically on our platform, it is 200ms
93996a9d26SFabio Baltieri 	 */
94996a9d26SFabio Baltieri 	if (!is_on)
95996a9d26SFabio Baltieri 		mdelay(200);
96996a9d26SFabio Baltieri 
97996a9d26SFabio Baltieri 	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
98996a9d26SFabio Baltieri 		usb_otg_state_string(musb->xceiv->state),
99996a9d26SFabio Baltieri 		musb_readb(musb->mregs, MUSB_DEVCTL));
100996a9d26SFabio Baltieri }
101996a9d26SFabio Baltieri 
1020135522cSFabio Baltieri static int musb_otg_notifications(struct notifier_block *nb,
1030135522cSFabio Baltieri 		unsigned long event, void *unused)
1040135522cSFabio Baltieri {
1050135522cSFabio Baltieri 	struct musb *musb = container_of(nb, struct musb, nb);
1060135522cSFabio Baltieri 
1070135522cSFabio Baltieri 	dev_dbg(musb->controller, "musb_otg_notifications %ld %s\n",
1080135522cSFabio Baltieri 			event, usb_otg_state_string(musb->xceiv->state));
1090135522cSFabio Baltieri 
1100135522cSFabio Baltieri 	switch (event) {
111af6882beSFabio Baltieri 	case UX500_MUSB_ID:
1120135522cSFabio Baltieri 		dev_dbg(musb->controller, "ID GND\n");
1130135522cSFabio Baltieri 		ux500_musb_set_vbus(musb, 1);
1140135522cSFabio Baltieri 		break;
115af6882beSFabio Baltieri 	case UX500_MUSB_VBUS:
1160135522cSFabio Baltieri 		dev_dbg(musb->controller, "VBUS Connect\n");
1170135522cSFabio Baltieri 		break;
118af6882beSFabio Baltieri 	case UX500_MUSB_NONE:
1190135522cSFabio Baltieri 		dev_dbg(musb->controller, "VBUS Disconnect\n");
1200135522cSFabio Baltieri 		if (is_host_active(musb))
1210135522cSFabio Baltieri 			ux500_musb_set_vbus(musb, 0);
1220135522cSFabio Baltieri 		else
1230135522cSFabio Baltieri 			musb->xceiv->state = OTG_STATE_B_IDLE;
1240135522cSFabio Baltieri 		break;
1250135522cSFabio Baltieri 	default:
1260135522cSFabio Baltieri 		dev_dbg(musb->controller, "ID float\n");
1270135522cSFabio Baltieri 		return NOTIFY_DONE;
1280135522cSFabio Baltieri 	}
1290135522cSFabio Baltieri 	return NOTIFY_OK;
1300135522cSFabio Baltieri }
1310135522cSFabio Baltieri 
132baef653aSPhilippe De Swert static irqreturn_t ux500_musb_interrupt(int irq, void *__hci)
133baef653aSPhilippe De Swert {
134baef653aSPhilippe De Swert 	unsigned long   flags;
135baef653aSPhilippe De Swert 	irqreturn_t     retval = IRQ_NONE;
136baef653aSPhilippe De Swert 	struct musb     *musb = __hci;
137baef653aSPhilippe De Swert 
138baef653aSPhilippe De Swert 	spin_lock_irqsave(&musb->lock, flags);
139baef653aSPhilippe De Swert 
140baef653aSPhilippe De Swert 	musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
141baef653aSPhilippe De Swert 	musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
142baef653aSPhilippe De Swert 	musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
143baef653aSPhilippe De Swert 
144baef653aSPhilippe De Swert 	if (musb->int_usb || musb->int_tx || musb->int_rx)
145baef653aSPhilippe De Swert 		retval = musb_interrupt(musb);
146baef653aSPhilippe De Swert 
147baef653aSPhilippe De Swert 	spin_unlock_irqrestore(&musb->lock, flags);
148baef653aSPhilippe De Swert 
149baef653aSPhilippe De Swert 	return retval;
150baef653aSPhilippe De Swert }
151baef653aSPhilippe De Swert 
1524bc36fd3SMian Yousaf Kaukab static int ux500_musb_init(struct musb *musb)
1534bc36fd3SMian Yousaf Kaukab {
1540135522cSFabio Baltieri 	int status;
1550135522cSFabio Baltieri 
156662dca54SKishon Vijay Abraham I 	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
157ded017eeSKishon Vijay Abraham I 	if (IS_ERR_OR_NULL(musb->xceiv)) {
1584bc36fd3SMian Yousaf Kaukab 		pr_err("HS USB OTG: no transceiver configured\n");
15925736e0cSMing Lei 		return -EPROBE_DEFER;
1604bc36fd3SMian Yousaf Kaukab 	}
1614bc36fd3SMian Yousaf Kaukab 
1620135522cSFabio Baltieri 	musb->nb.notifier_call = musb_otg_notifications;
1630135522cSFabio Baltieri 	status = usb_register_notifier(musb->xceiv, &musb->nb);
1640135522cSFabio Baltieri 	if (status < 0) {
1650135522cSFabio Baltieri 		dev_dbg(musb->controller, "notification register failed\n");
1660135522cSFabio Baltieri 		return status;
1670135522cSFabio Baltieri 	}
1680135522cSFabio Baltieri 
169baef653aSPhilippe De Swert 	musb->isr = ux500_musb_interrupt;
170baef653aSPhilippe De Swert 
1714bc36fd3SMian Yousaf Kaukab 	return 0;
1724bc36fd3SMian Yousaf Kaukab }
1734bc36fd3SMian Yousaf Kaukab 
1744bc36fd3SMian Yousaf Kaukab static int ux500_musb_exit(struct musb *musb)
1754bc36fd3SMian Yousaf Kaukab {
1760135522cSFabio Baltieri 	usb_unregister_notifier(musb->xceiv, &musb->nb);
1770135522cSFabio Baltieri 
178721002ecSKishon Vijay Abraham I 	usb_put_phy(musb->xceiv);
1794bc36fd3SMian Yousaf Kaukab 
1804bc36fd3SMian Yousaf Kaukab 	return 0;
1814bc36fd3SMian Yousaf Kaukab }
1824bc36fd3SMian Yousaf Kaukab 
1834bc36fd3SMian Yousaf Kaukab static const struct musb_platform_ops ux500_ops = {
1844bc36fd3SMian Yousaf Kaukab 	.init		= ux500_musb_init,
1854bc36fd3SMian Yousaf Kaukab 	.exit		= ux500_musb_exit,
186996a9d26SFabio Baltieri 
187996a9d26SFabio Baltieri 	.set_vbus	= ux500_musb_set_vbus,
1884bc36fd3SMian Yousaf Kaukab };
1894bc36fd3SMian Yousaf Kaukab 
19041ac7b3aSBill Pemberton static int ux500_probe(struct platform_device *pdev)
1914bc36fd3SMian Yousaf Kaukab {
19209fc7d22SFelipe Balbi 	struct resource musb_resources[2];
1934bc36fd3SMian Yousaf Kaukab 	struct musb_hdrc_platform_data	*pdata = pdev->dev.platform_data;
1944bc36fd3SMian Yousaf Kaukab 	struct platform_device		*musb;
1954bc36fd3SMian Yousaf Kaukab 	struct ux500_glue		*glue;
1964bc36fd3SMian Yousaf Kaukab 	struct clk			*clk;
1974bc36fd3SMian Yousaf Kaukab 	int				ret = -ENOMEM;
1984bc36fd3SMian Yousaf Kaukab 
1994bc36fd3SMian Yousaf Kaukab 	glue = kzalloc(sizeof(*glue), GFP_KERNEL);
2004bc36fd3SMian Yousaf Kaukab 	if (!glue) {
2014bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to allocate glue context\n");
2024bc36fd3SMian Yousaf Kaukab 		goto err0;
2034bc36fd3SMian Yousaf Kaukab 	}
2044bc36fd3SMian Yousaf Kaukab 
2052f771164SSebastian Andrzej Siewior 	musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
2064bc36fd3SMian Yousaf Kaukab 	if (!musb) {
2074bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to allocate musb device\n");
2082f771164SSebastian Andrzej Siewior 		goto err1;
2094bc36fd3SMian Yousaf Kaukab 	}
2104bc36fd3SMian Yousaf Kaukab 
2114bc36fd3SMian Yousaf Kaukab 	clk = clk_get(&pdev->dev, "usb");
2124bc36fd3SMian Yousaf Kaukab 	if (IS_ERR(clk)) {
2134bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to get clock\n");
2144bc36fd3SMian Yousaf Kaukab 		ret = PTR_ERR(clk);
21565b3d52dSB, Ravi 		goto err3;
2164bc36fd3SMian Yousaf Kaukab 	}
2174bc36fd3SMian Yousaf Kaukab 
21899d17cfaSFabio Baltieri 	ret = clk_prepare_enable(clk);
2194bc36fd3SMian Yousaf Kaukab 	if (ret) {
2204bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to enable clock\n");
22165b3d52dSB, Ravi 		goto err4;
2224bc36fd3SMian Yousaf Kaukab 	}
2234bc36fd3SMian Yousaf Kaukab 
2244bc36fd3SMian Yousaf Kaukab 	musb->dev.parent		= &pdev->dev;
22587266064SMian Yousaf Kaukab 	musb->dev.dma_mask		= pdev->dev.dma_mask;
22687266064SMian Yousaf Kaukab 	musb->dev.coherent_dma_mask	= pdev->dev.coherent_dma_mask;
2274bc36fd3SMian Yousaf Kaukab 
2284bc36fd3SMian Yousaf Kaukab 	glue->dev			= &pdev->dev;
2294bc36fd3SMian Yousaf Kaukab 	glue->musb			= musb;
2304bc36fd3SMian Yousaf Kaukab 	glue->clk			= clk;
2314bc36fd3SMian Yousaf Kaukab 
2324bc36fd3SMian Yousaf Kaukab 	pdata->platform_ops		= &ux500_ops;
2334bc36fd3SMian Yousaf Kaukab 
2344bc36fd3SMian Yousaf Kaukab 	platform_set_drvdata(pdev, glue);
2354bc36fd3SMian Yousaf Kaukab 
23609fc7d22SFelipe Balbi 	memset(musb_resources, 0x00, sizeof(*musb_resources) *
23709fc7d22SFelipe Balbi 			ARRAY_SIZE(musb_resources));
23809fc7d22SFelipe Balbi 
23909fc7d22SFelipe Balbi 	musb_resources[0].name = pdev->resource[0].name;
24009fc7d22SFelipe Balbi 	musb_resources[0].start = pdev->resource[0].start;
24109fc7d22SFelipe Balbi 	musb_resources[0].end = pdev->resource[0].end;
24209fc7d22SFelipe Balbi 	musb_resources[0].flags = pdev->resource[0].flags;
24309fc7d22SFelipe Balbi 
24409fc7d22SFelipe Balbi 	musb_resources[1].name = pdev->resource[1].name;
24509fc7d22SFelipe Balbi 	musb_resources[1].start = pdev->resource[1].start;
24609fc7d22SFelipe Balbi 	musb_resources[1].end = pdev->resource[1].end;
24709fc7d22SFelipe Balbi 	musb_resources[1].flags = pdev->resource[1].flags;
24809fc7d22SFelipe Balbi 
24909fc7d22SFelipe Balbi 	ret = platform_device_add_resources(musb, musb_resources,
25009fc7d22SFelipe Balbi 			ARRAY_SIZE(musb_resources));
2514bc36fd3SMian Yousaf Kaukab 	if (ret) {
2524bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to add resources\n");
25365b3d52dSB, Ravi 		goto err5;
2544bc36fd3SMian Yousaf Kaukab 	}
2554bc36fd3SMian Yousaf Kaukab 
2564bc36fd3SMian Yousaf Kaukab 	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
2574bc36fd3SMian Yousaf Kaukab 	if (ret) {
2584bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to add platform_data\n");
25965b3d52dSB, Ravi 		goto err5;
2604bc36fd3SMian Yousaf Kaukab 	}
2614bc36fd3SMian Yousaf Kaukab 
2624bc36fd3SMian Yousaf Kaukab 	ret = platform_device_add(musb);
2634bc36fd3SMian Yousaf Kaukab 	if (ret) {
2644bc36fd3SMian Yousaf Kaukab 		dev_err(&pdev->dev, "failed to register musb device\n");
26565b3d52dSB, Ravi 		goto err5;
2664bc36fd3SMian Yousaf Kaukab 	}
2674bc36fd3SMian Yousaf Kaukab 
2684bc36fd3SMian Yousaf Kaukab 	return 0;
2694bc36fd3SMian Yousaf Kaukab 
27065b3d52dSB, Ravi err5:
27199d17cfaSFabio Baltieri 	clk_disable_unprepare(clk);
2724bc36fd3SMian Yousaf Kaukab 
27365b3d52dSB, Ravi err4:
2744bc36fd3SMian Yousaf Kaukab 	clk_put(clk);
2754bc36fd3SMian Yousaf Kaukab 
27665b3d52dSB, Ravi err3:
2774bc36fd3SMian Yousaf Kaukab 	platform_device_put(musb);
2784bc36fd3SMian Yousaf Kaukab 
2794bc36fd3SMian Yousaf Kaukab err1:
2804bc36fd3SMian Yousaf Kaukab 	kfree(glue);
2814bc36fd3SMian Yousaf Kaukab 
2824bc36fd3SMian Yousaf Kaukab err0:
2834bc36fd3SMian Yousaf Kaukab 	return ret;
2844bc36fd3SMian Yousaf Kaukab }
2854bc36fd3SMian Yousaf Kaukab 
286fb4e98abSBill Pemberton static int ux500_remove(struct platform_device *pdev)
2874bc36fd3SMian Yousaf Kaukab {
2884bc36fd3SMian Yousaf Kaukab 	struct ux500_glue	*glue = platform_get_drvdata(pdev);
2894bc36fd3SMian Yousaf Kaukab 
2904b0de6f3SWei Yongjun 	platform_device_unregister(glue->musb);
29199d17cfaSFabio Baltieri 	clk_disable_unprepare(glue->clk);
2924bc36fd3SMian Yousaf Kaukab 	clk_put(glue->clk);
2934bc36fd3SMian Yousaf Kaukab 	kfree(glue);
2944bc36fd3SMian Yousaf Kaukab 
2954bc36fd3SMian Yousaf Kaukab 	return 0;
2964bc36fd3SMian Yousaf Kaukab }
2974bc36fd3SMian Yousaf Kaukab 
2984bc36fd3SMian Yousaf Kaukab #ifdef CONFIG_PM
2994bc36fd3SMian Yousaf Kaukab static int ux500_suspend(struct device *dev)
3004bc36fd3SMian Yousaf Kaukab {
3014bc36fd3SMian Yousaf Kaukab 	struct ux500_glue	*glue = dev_get_drvdata(dev);
3024bc36fd3SMian Yousaf Kaukab 	struct musb		*musb = glue_to_musb(glue);
3034bc36fd3SMian Yousaf Kaukab 
304b96d3b08SHeikki Krogerus 	usb_phy_set_suspend(musb->xceiv, 1);
30599d17cfaSFabio Baltieri 	clk_disable_unprepare(glue->clk);
3064bc36fd3SMian Yousaf Kaukab 
3074bc36fd3SMian Yousaf Kaukab 	return 0;
3084bc36fd3SMian Yousaf Kaukab }
3094bc36fd3SMian Yousaf Kaukab 
3104bc36fd3SMian Yousaf Kaukab static int ux500_resume(struct device *dev)
3114bc36fd3SMian Yousaf Kaukab {
3124bc36fd3SMian Yousaf Kaukab 	struct ux500_glue	*glue = dev_get_drvdata(dev);
3134bc36fd3SMian Yousaf Kaukab 	struct musb		*musb = glue_to_musb(glue);
3144bc36fd3SMian Yousaf Kaukab 	int			ret;
3154bc36fd3SMian Yousaf Kaukab 
31699d17cfaSFabio Baltieri 	ret = clk_prepare_enable(glue->clk);
3174bc36fd3SMian Yousaf Kaukab 	if (ret) {
3184bc36fd3SMian Yousaf Kaukab 		dev_err(dev, "failed to enable clock\n");
3194bc36fd3SMian Yousaf Kaukab 		return ret;
3204bc36fd3SMian Yousaf Kaukab 	}
3214bc36fd3SMian Yousaf Kaukab 
322b96d3b08SHeikki Krogerus 	usb_phy_set_suspend(musb->xceiv, 0);
3234bc36fd3SMian Yousaf Kaukab 
3244bc36fd3SMian Yousaf Kaukab 	return 0;
3254bc36fd3SMian Yousaf Kaukab }
3264bc36fd3SMian Yousaf Kaukab 
3274bc36fd3SMian Yousaf Kaukab static const struct dev_pm_ops ux500_pm_ops = {
3284bc36fd3SMian Yousaf Kaukab 	.suspend	= ux500_suspend,
3294bc36fd3SMian Yousaf Kaukab 	.resume		= ux500_resume,
3304bc36fd3SMian Yousaf Kaukab };
3314bc36fd3SMian Yousaf Kaukab 
3324bc36fd3SMian Yousaf Kaukab #define DEV_PM_OPS	(&ux500_pm_ops)
3334bc36fd3SMian Yousaf Kaukab #else
3344bc36fd3SMian Yousaf Kaukab #define DEV_PM_OPS	NULL
3354bc36fd3SMian Yousaf Kaukab #endif
3364bc36fd3SMian Yousaf Kaukab 
3374bc36fd3SMian Yousaf Kaukab static struct platform_driver ux500_driver = {
338e9e8c85eSFelipe Balbi 	.probe		= ux500_probe,
3397690417dSBill Pemberton 	.remove		= ux500_remove,
3404bc36fd3SMian Yousaf Kaukab 	.driver		= {
3414bc36fd3SMian Yousaf Kaukab 		.name	= "musb-ux500",
3424bc36fd3SMian Yousaf Kaukab 		.pm	= DEV_PM_OPS,
3434bc36fd3SMian Yousaf Kaukab 	},
3444bc36fd3SMian Yousaf Kaukab };
3454bc36fd3SMian Yousaf Kaukab 
3464bc36fd3SMian Yousaf Kaukab MODULE_DESCRIPTION("UX500 MUSB Glue Layer");
3474bc36fd3SMian Yousaf Kaukab MODULE_AUTHOR("Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>");
3484bc36fd3SMian Yousaf Kaukab MODULE_LICENSE("GPL v2");
3490e7090a6SSrinivas Kandagatla module_platform_driver(ux500_driver);
350