cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

da8xx.c (17548B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Texas Instruments DA8xx/OMAP-L1x "glue layer"
      4 *
      5 * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
      6 *
      7 * Based on the DaVinci "glue layer" code.
      8 * Copyright (C) 2005-2006 by Texas Instruments
      9 *
     10 * DT support
     11 * Copyright (c) 2016 Petr Kulhavy <petr@barix.com>
     12 *
     13 * This file is part of the Inventra Controller Driver for Linux.
     14 */
     15
     16#include <linux/module.h>
     17#include <linux/clk.h>
     18#include <linux/err.h>
     19#include <linux/io.h>
     20#include <linux/of_platform.h>
     21#include <linux/phy/phy.h>
     22#include <linux/platform_device.h>
     23#include <linux/dma-mapping.h>
     24#include <linux/usb/usb_phy_generic.h>
     25
     26#include "musb_core.h"
     27
     28/*
     29 * DA8XX specific definitions
     30 */
     31
     32/* USB 2.0 OTG module registers */
     33#define DA8XX_USB_REVISION_REG	0x00
     34#define DA8XX_USB_CTRL_REG	0x04
     35#define DA8XX_USB_STAT_REG	0x08
     36#define DA8XX_USB_EMULATION_REG 0x0c
     37#define DA8XX_USB_SRP_FIX_TIME_REG 0x18
     38#define DA8XX_USB_INTR_SRC_REG	0x20
     39#define DA8XX_USB_INTR_SRC_SET_REG 0x24
     40#define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28
     41#define DA8XX_USB_INTR_MASK_REG 0x2c
     42#define DA8XX_USB_INTR_MASK_SET_REG 0x30
     43#define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34
     44#define DA8XX_USB_INTR_SRC_MASKED_REG 0x38
     45#define DA8XX_USB_END_OF_INTR_REG 0x3c
     46#define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2))
     47
     48/* Control register bits */
     49#define DA8XX_SOFT_RESET_MASK	1
     50
     51#define DA8XX_USB_TX_EP_MASK	0x1f		/* EP0 + 4 Tx EPs */
     52#define DA8XX_USB_RX_EP_MASK	0x1e		/* 4 Rx EPs */
     53
     54/* USB interrupt register bits */
     55#define DA8XX_INTR_USB_SHIFT	16
     56#define DA8XX_INTR_USB_MASK	(0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */
     57					/* interrupts and DRVVBUS interrupt */
     58#define DA8XX_INTR_DRVVBUS	0x100
     59#define DA8XX_INTR_RX_SHIFT	8
     60#define DA8XX_INTR_RX_MASK	(DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT)
     61#define DA8XX_INTR_TX_SHIFT	0
     62#define DA8XX_INTR_TX_MASK	(DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT)
     63
     64#define DA8XX_MENTOR_CORE_OFFSET 0x400
     65
     66struct da8xx_glue {
     67	struct device		*dev;
     68	struct platform_device	*musb;
     69	struct platform_device	*usb_phy;
     70	struct clk		*clk;
     71	struct phy		*phy;
     72};
     73
     74/*
     75 * Because we don't set CTRL.UINT, it's "important" to:
     76 *	- not read/write INTRUSB/INTRUSBE (except during
     77 *	  initial setup, as a workaround);
     78 *	- use INTSET/INTCLR instead.
     79 */
     80
     81/**
     82 * da8xx_musb_enable - enable interrupts
     83 */
     84static void da8xx_musb_enable(struct musb *musb)
     85{
     86	void __iomem *reg_base = musb->ctrl_base;
     87	u32 mask;
     88
     89	/* Workaround: setup IRQs through both register sets. */
     90	mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) |
     91	       ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) |
     92	       DA8XX_INTR_USB_MASK;
     93	musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask);
     94
     95	/* Force the DRVVBUS IRQ so we can start polling for ID change. */
     96	musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG,
     97			DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT);
     98}
     99
    100/**
    101 * da8xx_musb_disable - disable HDRC and flush interrupts
    102 */
    103static void da8xx_musb_disable(struct musb *musb)
    104{
    105	void __iomem *reg_base = musb->ctrl_base;
    106
    107	musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
    108		    DA8XX_INTR_USB_MASK |
    109		    DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
    110	musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
    111}
    112
    113#define portstate(stmt)		stmt
    114
    115static void da8xx_musb_set_vbus(struct musb *musb, int is_on)
    116{
    117	WARN_ON(is_on && is_peripheral_active(musb));
    118}
    119
    120#define	POLL_SECONDS	2
    121
    122static void otg_timer(struct timer_list *t)
    123{
    124	struct musb		*musb = from_timer(musb, t, dev_timer);
    125	void __iomem		*mregs = musb->mregs;
    126	u8			devctl;
    127	unsigned long		flags;
    128
    129	/*
    130	 * We poll because DaVinci's won't expose several OTG-critical
    131	 * status change events (from the transceiver) otherwise.
    132	 */
    133	devctl = musb_readb(mregs, MUSB_DEVCTL);
    134	dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
    135		usb_otg_state_string(musb->xceiv->otg->state));
    136
    137	spin_lock_irqsave(&musb->lock, flags);
    138	switch (musb->xceiv->otg->state) {
    139	case OTG_STATE_A_WAIT_BCON:
    140		devctl &= ~MUSB_DEVCTL_SESSION;
    141		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
    142
    143		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
    144		if (devctl & MUSB_DEVCTL_BDEVICE) {
    145			musb->xceiv->otg->state = OTG_STATE_B_IDLE;
    146			MUSB_DEV_MODE(musb);
    147		} else {
    148			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
    149			MUSB_HST_MODE(musb);
    150		}
    151		break;
    152	case OTG_STATE_A_WAIT_VFALL:
    153		/*
    154		 * Wait till VBUS falls below SessionEnd (~0.2 V); the 1.3
    155		 * RTL seems to mis-handle session "start" otherwise (or in
    156		 * our case "recover"), in routine "VBUS was valid by the time
    157		 * VBUSERR got reported during enumeration" cases.
    158		 */
    159		if (devctl & MUSB_DEVCTL_VBUS) {
    160			mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
    161			break;
    162		}
    163		musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
    164		musb_writel(musb->ctrl_base, DA8XX_USB_INTR_SRC_SET_REG,
    165			    MUSB_INTR_VBUSERROR << DA8XX_INTR_USB_SHIFT);
    166		break;
    167	case OTG_STATE_B_IDLE:
    168		/*
    169		 * There's no ID-changed IRQ, so we have no good way to tell
    170		 * when to switch to the A-Default state machine (by setting
    171		 * the DEVCTL.Session bit).
    172		 *
    173		 * Workaround:  whenever we're in B_IDLE, try setting the
    174		 * session flag every few seconds.  If it works, ID was
    175		 * grounded and we're now in the A-Default state machine.
    176		 *
    177		 * NOTE: setting the session flag is _supposed_ to trigger
    178		 * SRP but clearly it doesn't.
    179		 */
    180		musb_writeb(mregs, MUSB_DEVCTL, devctl | MUSB_DEVCTL_SESSION);
    181		devctl = musb_readb(mregs, MUSB_DEVCTL);
    182		if (devctl & MUSB_DEVCTL_BDEVICE)
    183			mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
    184		else
    185			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
    186		break;
    187	default:
    188		break;
    189	}
    190	spin_unlock_irqrestore(&musb->lock, flags);
    191}
    192
    193static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout)
    194{
    195	static unsigned long last_timer;
    196
    197	if (timeout == 0)
    198		timeout = jiffies + msecs_to_jiffies(3);
    199
    200	/* Never idle if active, or when VBUS timeout is not set as host */
    201	if (musb->is_active || (musb->a_wait_bcon == 0 &&
    202				musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) {
    203		dev_dbg(musb->controller, "%s active, deleting timer\n",
    204			usb_otg_state_string(musb->xceiv->otg->state));
    205		del_timer(&musb->dev_timer);
    206		last_timer = jiffies;
    207		return;
    208	}
    209
    210	if (time_after(last_timer, timeout) && timer_pending(&musb->dev_timer)) {
    211		dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n");
    212		return;
    213	}
    214	last_timer = timeout;
    215
    216	dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
    217		usb_otg_state_string(musb->xceiv->otg->state),
    218		jiffies_to_msecs(timeout - jiffies));
    219	mod_timer(&musb->dev_timer, timeout);
    220}
    221
    222static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
    223{
    224	struct musb		*musb = hci;
    225	void __iomem		*reg_base = musb->ctrl_base;
    226	unsigned long		flags;
    227	irqreturn_t		ret = IRQ_NONE;
    228	u32			status;
    229
    230	spin_lock_irqsave(&musb->lock, flags);
    231
    232	/*
    233	 * NOTE: DA8XX shadows the Mentor IRQs.  Don't manage them through
    234	 * the Mentor registers (except for setup), use the TI ones and EOI.
    235	 */
    236
    237	/* Acknowledge and handle non-CPPI interrupts */
    238	status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG);
    239	if (!status)
    240		goto eoi;
    241
    242	musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status);
    243	dev_dbg(musb->controller, "USB IRQ %08x\n", status);
    244
    245	musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT;
    246	musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT;
    247	musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT;
    248
    249	/*
    250	 * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
    251	 * DA8xx's missing ID change IRQ.  We need an ID change IRQ to
    252	 * switch appropriately between halves of the OTG state machine.
    253	 * Managing DEVCTL.Session per Mentor docs requires that we know its
    254	 * value but DEVCTL.BDevice is invalid without DEVCTL.Session set.
    255	 * Also, DRVVBUS pulses for SRP (but not at 5 V)...
    256	 */
    257	if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) {
    258		int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG);
    259		void __iomem *mregs = musb->mregs;
    260		u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
    261		int err;
    262
    263		err = musb->int_usb & MUSB_INTR_VBUSERROR;
    264		if (err) {
    265			/*
    266			 * The Mentor core doesn't debounce VBUS as needed
    267			 * to cope with device connect current spikes. This
    268			 * means it's not uncommon for bus-powered devices
    269			 * to get VBUS errors during enumeration.
    270			 *
    271			 * This is a workaround, but newer RTL from Mentor
    272			 * seems to allow a better one: "re"-starting sessions
    273			 * without waiting for VBUS to stop registering in
    274			 * devctl.
    275			 */
    276			musb->int_usb &= ~MUSB_INTR_VBUSERROR;
    277			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL;
    278			mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
    279			WARNING("VBUS error workaround (delay coming)\n");
    280		} else if (drvvbus) {
    281			MUSB_HST_MODE(musb);
    282			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
    283			portstate(musb->port1_status |= USB_PORT_STAT_POWER);
    284			del_timer(&musb->dev_timer);
    285		} else if (!(musb->int_usb & MUSB_INTR_BABBLE)) {
    286			/*
    287			 * When babble condition happens, drvvbus interrupt
    288			 * is also generated. Ignore this drvvbus interrupt
    289			 * and let babble interrupt handler recovers the
    290			 * controller; otherwise, the host-mode flag is lost
    291			 * due to the MUSB_DEV_MODE() call below and babble
    292			 * recovery logic will not be called.
    293			 */
    294			musb->is_active = 0;
    295			MUSB_DEV_MODE(musb);
    296			musb->xceiv->otg->state = OTG_STATE_B_IDLE;
    297			portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
    298		}
    299
    300		dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
    301				drvvbus ? "on" : "off",
    302				usb_otg_state_string(musb->xceiv->otg->state),
    303				err ? " ERROR" : "",
    304				devctl);
    305		ret = IRQ_HANDLED;
    306	}
    307
    308	if (musb->int_tx || musb->int_rx || musb->int_usb)
    309		ret |= musb_interrupt(musb);
    310
    311 eoi:
    312	/* EOI needs to be written for the IRQ to be re-asserted. */
    313	if (ret == IRQ_HANDLED || status)
    314		musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
    315
    316	/* Poll for ID change */
    317	if (musb->xceiv->otg->state == OTG_STATE_B_IDLE)
    318		mod_timer(&musb->dev_timer, jiffies + POLL_SECONDS * HZ);
    319
    320	spin_unlock_irqrestore(&musb->lock, flags);
    321
    322	return ret;
    323}
    324
    325static int da8xx_musb_set_mode(struct musb *musb, u8 musb_mode)
    326{
    327	struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent);
    328	enum phy_mode phy_mode;
    329
    330	/*
    331	 * The PHY has some issues when it is forced in device or host mode.
    332	 * Unless the user request another mode, configure the PHY in OTG mode.
    333	 */
    334	if (!musb->is_initialized)
    335		return phy_set_mode(glue->phy, PHY_MODE_USB_OTG);
    336
    337	switch (musb_mode) {
    338	case MUSB_HOST:		/* Force VBUS valid, ID = 0 */
    339		phy_mode = PHY_MODE_USB_HOST;
    340		break;
    341	case MUSB_PERIPHERAL:	/* Force VBUS valid, ID = 1 */
    342		phy_mode = PHY_MODE_USB_DEVICE;
    343		break;
    344	case MUSB_OTG:		/* Don't override the VBUS/ID comparators */
    345		phy_mode = PHY_MODE_USB_OTG;
    346		break;
    347	default:
    348		return -EINVAL;
    349	}
    350
    351	return phy_set_mode(glue->phy, phy_mode);
    352}
    353
    354static int da8xx_musb_init(struct musb *musb)
    355{
    356	struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent);
    357	void __iomem *reg_base = musb->ctrl_base;
    358	u32 rev;
    359	int ret = -ENODEV;
    360
    361	musb->mregs += DA8XX_MENTOR_CORE_OFFSET;
    362
    363	ret = clk_prepare_enable(glue->clk);
    364	if (ret) {
    365		dev_err(glue->dev, "failed to enable clock\n");
    366		return ret;
    367	}
    368
    369	/* Returns zero if e.g. not clocked */
    370	rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG);
    371	if (!rev)
    372		goto fail;
    373
    374	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
    375	if (IS_ERR_OR_NULL(musb->xceiv)) {
    376		ret = -EPROBE_DEFER;
    377		goto fail;
    378	}
    379
    380	timer_setup(&musb->dev_timer, otg_timer, 0);
    381
    382	/* Reset the controller */
    383	musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);
    384
    385	/* Start the on-chip PHY and its PLL. */
    386	ret = phy_init(glue->phy);
    387	if (ret) {
    388		dev_err(glue->dev, "Failed to init phy.\n");
    389		goto fail;
    390	}
    391
    392	ret = phy_power_on(glue->phy);
    393	if (ret) {
    394		dev_err(glue->dev, "Failed to power on phy.\n");
    395		goto err_phy_power_on;
    396	}
    397
    398	msleep(5);
    399
    400	/* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */
    401	pr_debug("DA8xx OTG revision %08x, control %02x\n", rev,
    402		 musb_readb(reg_base, DA8XX_USB_CTRL_REG));
    403
    404	musb->isr = da8xx_musb_interrupt;
    405	return 0;
    406
    407err_phy_power_on:
    408	phy_exit(glue->phy);
    409fail:
    410	clk_disable_unprepare(glue->clk);
    411	return ret;
    412}
    413
    414static int da8xx_musb_exit(struct musb *musb)
    415{
    416	struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent);
    417
    418	del_timer_sync(&musb->dev_timer);
    419
    420	phy_power_off(glue->phy);
    421	phy_exit(glue->phy);
    422	clk_disable_unprepare(glue->clk);
    423
    424	usb_put_phy(musb->xceiv);
    425
    426	return 0;
    427}
    428
    429static inline u8 get_vbus_power(struct device *dev)
    430{
    431	struct regulator *vbus_supply;
    432	int current_uA;
    433
    434	vbus_supply = regulator_get_optional(dev, "vbus");
    435	if (IS_ERR(vbus_supply))
    436		return 255;
    437	current_uA = regulator_get_current_limit(vbus_supply);
    438	regulator_put(vbus_supply);
    439	if (current_uA <= 0 || current_uA > 510000)
    440		return 255;
    441	return current_uA / 1000 / 2;
    442}
    443
    444#ifdef CONFIG_USB_TI_CPPI41_DMA
    445static void da8xx_dma_controller_callback(struct dma_controller *c)
    446{
    447	struct musb *musb = c->musb;
    448	void __iomem *reg_base = musb->ctrl_base;
    449
    450	musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
    451}
    452
    453static struct dma_controller *
    454da8xx_dma_controller_create(struct musb *musb, void __iomem *base)
    455{
    456	struct dma_controller *controller;
    457
    458	controller = cppi41_dma_controller_create(musb, base);
    459	if (IS_ERR_OR_NULL(controller))
    460		return controller;
    461
    462	controller->dma_callback = da8xx_dma_controller_callback;
    463
    464	return controller;
    465}
    466#endif
    467
    468static const struct musb_platform_ops da8xx_ops = {
    469	.quirks		= MUSB_INDEXED_EP | MUSB_PRESERVE_SESSION |
    470			  MUSB_DMA_CPPI41 | MUSB_DA8XX,
    471	.init		= da8xx_musb_init,
    472	.exit		= da8xx_musb_exit,
    473
    474	.fifo_mode	= 2,
    475#ifdef CONFIG_USB_TI_CPPI41_DMA
    476	.dma_init	= da8xx_dma_controller_create,
    477	.dma_exit	= cppi41_dma_controller_destroy,
    478#endif
    479	.enable		= da8xx_musb_enable,
    480	.disable	= da8xx_musb_disable,
    481
    482	.set_mode	= da8xx_musb_set_mode,
    483	.try_idle	= da8xx_musb_try_idle,
    484
    485	.set_vbus	= da8xx_musb_set_vbus,
    486};
    487
    488static const struct platform_device_info da8xx_dev_info = {
    489	.name		= "musb-hdrc",
    490	.id		= PLATFORM_DEVID_AUTO,
    491	.dma_mask	= DMA_BIT_MASK(32),
    492};
    493
    494static const struct musb_hdrc_config da8xx_config = {
    495	.ram_bits = 10,
    496	.num_eps = 5,
    497	.multipoint = 1,
    498};
    499
    500static struct of_dev_auxdata da8xx_auxdata_lookup[] = {
    501	OF_DEV_AUXDATA("ti,da830-cppi41", 0x01e01000, "cppi41-dmaengine",
    502		       NULL),
    503	{}
    504};
    505
    506static int da8xx_probe(struct platform_device *pdev)
    507{
    508	struct musb_hdrc_platform_data	*pdata = dev_get_platdata(&pdev->dev);
    509	struct da8xx_glue		*glue;
    510	struct platform_device_info	pinfo;
    511	struct clk			*clk;
    512	struct device_node		*np = pdev->dev.of_node;
    513	int				ret;
    514
    515	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
    516	if (!glue)
    517		return -ENOMEM;
    518
    519	clk = devm_clk_get(&pdev->dev, NULL);
    520	if (IS_ERR(clk)) {
    521		dev_err(&pdev->dev, "failed to get clock\n");
    522		return PTR_ERR(clk);
    523	}
    524
    525	glue->phy = devm_phy_get(&pdev->dev, "usb-phy");
    526	if (IS_ERR(glue->phy)) {
    527		if (PTR_ERR(glue->phy) != -EPROBE_DEFER)
    528			dev_err(&pdev->dev, "failed to get phy\n");
    529		return PTR_ERR(glue->phy);
    530	}
    531
    532	glue->dev			= &pdev->dev;
    533	glue->clk			= clk;
    534
    535	if (IS_ENABLED(CONFIG_OF) && np) {
    536		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
    537		if (!pdata)
    538			return -ENOMEM;
    539
    540		pdata->config	= &da8xx_config;
    541		pdata->mode	= musb_get_mode(&pdev->dev);
    542		pdata->power	= get_vbus_power(&pdev->dev);
    543	}
    544
    545	pdata->platform_ops		= &da8xx_ops;
    546
    547	glue->usb_phy = usb_phy_generic_register();
    548	ret = PTR_ERR_OR_ZERO(glue->usb_phy);
    549	if (ret) {
    550		dev_err(&pdev->dev, "failed to register usb_phy\n");
    551		return ret;
    552	}
    553	platform_set_drvdata(pdev, glue);
    554
    555	ret = of_platform_populate(pdev->dev.of_node, NULL,
    556				   da8xx_auxdata_lookup, &pdev->dev);
    557	if (ret)
    558		return ret;
    559
    560	pinfo = da8xx_dev_info;
    561	pinfo.parent = &pdev->dev;
    562	pinfo.res = pdev->resource;
    563	pinfo.num_res = pdev->num_resources;
    564	pinfo.data = pdata;
    565	pinfo.size_data = sizeof(*pdata);
    566	pinfo.fwnode = of_fwnode_handle(np);
    567	pinfo.of_node_reused = true;
    568
    569	glue->musb = platform_device_register_full(&pinfo);
    570	ret = PTR_ERR_OR_ZERO(glue->musb);
    571	if (ret) {
    572		dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
    573		usb_phy_generic_unregister(glue->usb_phy);
    574	}
    575
    576	return ret;
    577}
    578
    579static int da8xx_remove(struct platform_device *pdev)
    580{
    581	struct da8xx_glue		*glue = platform_get_drvdata(pdev);
    582
    583	platform_device_unregister(glue->musb);
    584	usb_phy_generic_unregister(glue->usb_phy);
    585
    586	return 0;
    587}
    588
    589#ifdef CONFIG_PM_SLEEP
    590static int da8xx_suspend(struct device *dev)
    591{
    592	int ret;
    593	struct da8xx_glue *glue = dev_get_drvdata(dev);
    594
    595	ret = phy_power_off(glue->phy);
    596	if (ret)
    597		return ret;
    598	clk_disable_unprepare(glue->clk);
    599
    600	return 0;
    601}
    602
    603static int da8xx_resume(struct device *dev)
    604{
    605	int ret;
    606	struct da8xx_glue *glue = dev_get_drvdata(dev);
    607
    608	ret = clk_prepare_enable(glue->clk);
    609	if (ret)
    610		return ret;
    611	return phy_power_on(glue->phy);
    612}
    613#endif
    614
    615static SIMPLE_DEV_PM_OPS(da8xx_pm_ops, da8xx_suspend, da8xx_resume);
    616
    617#ifdef CONFIG_OF
    618static const struct of_device_id da8xx_id_table[] = {
    619	{
    620		.compatible = "ti,da830-musb",
    621	},
    622	{},
    623};
    624MODULE_DEVICE_TABLE(of, da8xx_id_table);
    625#endif
    626
    627static struct platform_driver da8xx_driver = {
    628	.probe		= da8xx_probe,
    629	.remove		= da8xx_remove,
    630	.driver		= {
    631		.name	= "musb-da8xx",
    632		.pm = &da8xx_pm_ops,
    633		.of_match_table = of_match_ptr(da8xx_id_table),
    634	},
    635};
    636
    637MODULE_DESCRIPTION("DA8xx/OMAP-L1x MUSB Glue Layer");
    638MODULE_AUTHOR("Sergei Shtylyov <sshtylyov@ru.mvista.com>");
    639MODULE_LICENSE("GPL v2");
    640module_platform_driver(da8xx_driver);