Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5027070b authored by Anoop P A's avatar Anoop P A Committed by Ralf Baechle
Browse files

MIPS: MSP71xx: Platform support for MSP on-chip USB controller.



Signed-off-by: default avatarAnoop P A <anoop.pa@gmail.com>
To: linux-mips@linux-mips.org
To: linux-kernel@vger.kernel.org
Cc: Anoop P A <anoop.pa@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/2043/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 088f3876
Loading
Loading
Loading
Loading
+9 −8
Original line number Original line Diff line number Diff line
@@ -91,12 +91,10 @@
					/* MAC C device registers       */
					/* MAC C device registers       */
#define MSP_ADSL2_BASE		(MSP_MSB_BASE + 0xA80000)
#define MSP_ADSL2_BASE		(MSP_MSB_BASE + 0xA80000)
					/* ADSL2 device registers       */
					/* ADSL2 device registers       */
#define MSP_USB_BASE		(MSP_MSB_BASE + 0xB40000)
#define MSP_USB0_BASE		(MSP_MSB_BASE + 0xB00000)
					/* USB device registers         */
					/* USB0 device registers        */
#define MSP_USB_BASE_START	(MSP_MSB_BASE + 0xB40100)
#define MSP_USB1_BASE		(MSP_MSB_BASE + 0x300000)
					/* USB device registers         */
					/* USB1 device registers	*/
#define MSP_USB_BASE_END	(MSP_MSB_BASE + 0xB401FF)
					/* USB device registers         */
#define MSP_CPUIF_BASE		(MSP_MSB_BASE + 0xC00000)
#define MSP_CPUIF_BASE		(MSP_MSB_BASE + 0xC00000)
					/* CPU interface registers      */
					/* CPU interface registers      */


@@ -319,8 +317,11 @@
#define CPU_ERR2_REG		regptr(MSP_SLP_BASE + 0x184)
#define CPU_ERR2_REG		regptr(MSP_SLP_BASE + 0x184)
					/* CPU/SLP Error status 1       */
					/* CPU/SLP Error status 1       */


#define EXTENDED_GPIO_REG	regptr(MSP_SLP_BASE + 0x188)
/* Extended GPIO registers       */
					/* Extended GPIO register       */
#define EXTENDED_GPIO1_REG	regptr(MSP_SLP_BASE + 0x188)
#define EXTENDED_GPIO2_REG	regptr(MSP_SLP_BASE + 0x18c)
#define EXTENDED_GPIO_REG	EXTENDED_GPIO1_REG
					/* Backward-compatibility	*/


/* System Error registers */
/* System Error registers */
#define SLP_ERR_STS_REG		regptr(MSP_SLP_BASE + 0x190)
#define SLP_ERR_STS_REG		regptr(MSP_SLP_BASE + 0x190)
+144 −0
Original line number Original line Diff line number Diff line
/******************************************************************
 * Copyright (c) 2000-2007 PMC-Sierra INC.
 *
 *     This program is free software; you can redistribute it
 *     and/or modify it under the terms of the GNU General
 *     Public License as published by the Free Software
 *     Foundation; either version 2 of the License, or (at your
 *     option) any later version.
 *
 *     This program is distributed in the hope that it will be
 *     useful, but WITHOUT ANY WARRANTY; without even the implied
 *     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *     PURPOSE.  See the GNU General Public License for more
 *     details.
 *
 *     You should have received a copy of the GNU General Public
 *     License along with this program; if not, write to the Free
 *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
 *     02139, USA.
 *
 * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
 * SOFTWARE.
 */
#ifndef MSP_USB_H_
#define MSP_USB_H_

#ifdef CONFIG_MSP_HAS_DUAL_USB
#define NUM_USB_DEVS   2
#else
#define NUM_USB_DEVS   1
#endif

/* Register spaces for USB host 0 */
#define MSP_USB0_MAB_START	(MSP_USB0_BASE + 0x0)
#define MSP_USB0_MAB_END	(MSP_USB0_BASE + 0x17)
#define MSP_USB0_ID_START	(MSP_USB0_BASE + 0x40000)
#define MSP_USB0_ID_END		(MSP_USB0_BASE + 0x4008f)
#define MSP_USB0_HS_START	(MSP_USB0_BASE + 0x40100)
#define MSP_USB0_HS_END		(MSP_USB0_BASE + 0x401FF)

/* Register spaces for USB host 1 */
#define	MSP_USB1_MAB_START	(MSP_USB1_BASE + 0x0)
#define MSP_USB1_MAB_END	(MSP_USB1_BASE + 0x17)
#define MSP_USB1_ID_START	(MSP_USB1_BASE + 0x40000)
#define MSP_USB1_ID_END		(MSP_USB1_BASE + 0x4008f)
#define MSP_USB1_HS_START	(MSP_USB1_BASE + 0x40100)
#define MSP_USB1_HS_END		(MSP_USB1_BASE + 0x401ff)

/* USB Identification registers */
struct msp_usbid_regs {
	u32 id;		/* 0x0: Identification register */
	u32 hwgen;	/* 0x4: General HW params */
	u32 hwhost;	/* 0x8: Host HW params */
	u32 hwdev;	/* 0xc: Device HW params */
	u32 hwtxbuf;	/* 0x10: Tx buffer HW params */
	u32 hwrxbuf;	/* 0x14: Rx buffer HW params */
	u32 reserved[26];
	u32 timer0_load; /* 0x80: General-purpose timer 0 load*/
	u32 timer0_ctrl; /* 0x84: General-purpose timer 0 control */
	u32 timer1_load; /* 0x88: General-purpose timer 1 load*/
	u32 timer1_ctrl; /* 0x8c: General-purpose timer 1 control */
};

/* MSBus to AMBA registers */
struct msp_mab_regs {
	u32 isr;	/* 0x0: Interrupt status */
	u32 imr;	/* 0x4: Interrupt mask */
	u32 thcr0;	/* 0x8: Transaction header capture 0 */
	u32 thcr1;	/* 0xc: Transaction header capture 1 */
	u32 int_stat;	/* 0x10: Interrupt status summary */
	u32 phy_cfg;	/* 0x14: USB phy config */
};

/* EHCI registers */
struct msp_usbhs_regs {
	u32 hciver;	/* 0x0: Version and offset to operational regs */
	u32 hcsparams;	/* 0x4: Host control structural parameters */
	u32 hccparams;	/* 0x8: Host control capability parameters */
	u32 reserved0[5];
	u32 dciver;	/* 0x20: Device interface version */
	u32 dccparams;	/* 0x24: Device control capability parameters */
	u32 reserved1[6];
	u32 cmd;	/* 0x40: USB command */
	u32 sts;	/* 0x44: USB status */
	u32 int_ena;	/* 0x48: USB interrupt enable */
	u32 frindex;	/* 0x4c: Frame index */
	u32 reserved3;
	union {
		struct {
			u32 flb_addr; /* 0x54: Frame list base address */
			u32 next_async_addr; /* 0x58: next asynchronous addr */
			u32 ttctrl; /* 0x5c: embedded transaction translator
							async buffer status */
			u32 burst_size; /* 0x60: Controller burst size */
			u32 tx_fifo_ctrl; /* 0x64: Tx latency FIFO tuning */
			u32 reserved0[4];
			u32 endpt_nak; /* 0x78: Endpoint NAK */
			u32 endpt_nak_ena; /* 0x7c: Endpoint NAK enable */
			u32 cfg_flag; /* 0x80: Config flag */
			u32 port_sc1; /* 0x84: Port status & control 1 */
			u32 reserved1[7];
			u32 otgsc;	/* 0xa4: OTG status & control */
			u32 mode;	/* 0xa8: USB controller mode */
		} host;

		struct {
			u32 dev_addr; /* 0x54: Device address */
			u32 endpt_list_addr; /* 0x58: Endpoint list address */
			u32 reserved0[7];
			u32 endpt_nak;	/* 0x74 */
			u32 endpt_nak_ctrl; /* 0x78 */
			u32 cfg_flag; /* 0x80 */
			u32 port_sc1; /* 0x84: Port status & control 1 */
			u32 reserved[7];
			u32 otgsc;	/* 0xa4: OTG status & control */
			u32 mode;	/* 0xa8: USB controller mode */
			u32 endpt_setup_stat; /* 0xac */
			u32 endpt_prime; /* 0xb0 */
			u32 endpt_flush; /* 0xb4 */
			u32 endpt_stat; /* 0xb8 */
			u32 endpt_complete; /* 0xbc */
			u32 endpt_ctrl0; /* 0xc0 */
			u32 endpt_ctrl1; /* 0xc4 */
			u32 endpt_ctrl2; /* 0xc8 */
			u32 endpt_ctrl3; /* 0xcc */
		} device;
	} u;
};
/*
 * Container for the more-generic platform_device.
 * This exists mainly as a way to map the non-standard register
 * spaces and make them accessible to the USB ISR.
 */
struct mspusb_device {
	struct msp_mab_regs   __iomem *mab_regs;
	struct msp_usbid_regs __iomem *usbid_regs;
	struct msp_usbhs_regs __iomem *usbhs_regs;
	struct platform_device dev;
};

#define to_mspusb_device(x) container_of((x), struct mspusb_device, dev)
#define TO_HOST_ID(x) ((x) & 0x3)
#endif /*MSP_USB_H_*/
+5 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ config PMC_MSP7120_GW
	select SYS_SUPPORTS_MULTITHREADING
	select SYS_SUPPORTS_MULTITHREADING
	select IRQ_MSP_CIC
	select IRQ_MSP_CIC
	select HW_HAS_PCI
	select HW_HAS_PCI
	select MSP_HAS_USB


config PMC_MSP7120_FPGA
config PMC_MSP7120_FPGA
	bool "PMC-Sierra MSP7120 FPGA"
	bool "PMC-Sierra MSP7120 FPGA"
@@ -35,3 +36,7 @@ endchoice
config HYPERTRANSPORT
config HYPERTRANSPORT
	bool "Hypertransport Support for PMC-Sierra Yosemite"
	bool "Hypertransport Support for PMC-Sierra Yosemite"
	depends on PMC_YOSEMITE
	depends on PMC_YOSEMITE

config MSP_HAS_USB
	boolean
	depends on PMC_MSP
+1 −1
Original line number Original line Diff line number Diff line
@@ -9,6 +9,6 @@ obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
obj-$(CONFIG_PCI) += msp_pci.o
obj-$(CONFIG_PCI) += msp_pci.o
obj-$(CONFIG_MSPETH) += msp_eth.o
obj-$(CONFIG_MSPETH) += msp_eth.o
obj-$(CONFIG_USB_MSP71XX) += msp_usb.o
obj-$(CONFIG_MSP_HAS_USB) += msp_usb.o
obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o
obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o
obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o
obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o
+176 −63
Original line number Original line Diff line number Diff line
/*
/*
 * The setup file for USB related hardware on PMC-Sierra MSP processors.
 * The setup file for USB related hardware on PMC-Sierra MSP processors.
 *
 *
 * Copyright 2006-2007 PMC-Sierra, Inc.
 * Copyright 2006 PMC-Sierra, Inc.
 *
 *
 * This program is free software; you can redistribute  it and/or modify it
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * under  the terms of  the GNU General  Public License as published by the
@@ -23,8 +23,8 @@
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
 */
#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)


#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
@@ -34,12 +34,14 @@
#include <msp_regs.h>
#include <msp_regs.h>
#include <msp_int.h>
#include <msp_int.h>
#include <msp_prom.h>
#include <msp_prom.h>
#include <msp_usb.h>



#if defined(CONFIG_USB_EHCI_HCD)
#if defined(CONFIG_USB_EHCI_HCD)
static struct resource msp_usbhost_resources [] = {
static struct resource msp_usbhost0_resources[] = {
	[0] = {
	[0] = { /* EHCI-HS operational and capabilities registers */
		.start	= MSP_USB_BASE_START,
		.start  = MSP_USB0_HS_START,
		.end	= MSP_USB_BASE_END,
		.end    = MSP_USB0_HS_END,
		.flags  = IORESOURCE_MEM,
		.flags  = IORESOURCE_MEM,
	},
	},
	[1] = {
	[1] = {
@@ -47,27 +49,80 @@ static struct resource msp_usbhost_resources [] = {
		.end    = MSP_INT_USB,
		.end    = MSP_INT_USB,
		.flags  = IORESOURCE_IRQ,
		.flags  = IORESOURCE_IRQ,
	},
	},
	[2] = { /* MSBus-to-AMBA bridge register space */
		.start	= MSP_USB0_MAB_START,
		.end	= MSP_USB0_MAB_END,
		.flags	= IORESOURCE_MEM,
	},
	[3] = { /* Identification and general hardware parameters */
		.start	= MSP_USB0_ID_START,
		.end	= MSP_USB0_ID_END,
		.flags	= IORESOURCE_MEM,
	},
};
};


static u64 msp_usbhost_dma_mask = DMA_BIT_MASK(32);
static u64 msp_usbhost0_dma_mask = 0xffffffffUL;


static struct platform_device msp_usbhost_device = {
static struct mspusb_device msp_usbhost0_device = {
	.dev	= {
		.name	= "pmcmsp-ehci",
		.name	= "pmcmsp-ehci",
		.id	= 0,
		.id	= 0,
		.dev	= {
		.dev	= {
		.dma_mask = &msp_usbhost_dma_mask,
			.dma_mask = &msp_usbhost0_dma_mask,
		.coherent_dma_mask = DMA_BIT_MASK(32),
			.coherent_dma_mask = 0xffffffffUL,
		},
		.num_resources  = ARRAY_SIZE(msp_usbhost0_resources),
		.resource       = msp_usbhost0_resources,
	},
};

/* MSP7140/MSP82XX has two USB2 hosts. */
#ifdef CONFIG_MSP_HAS_DUAL_USB
static u64 msp_usbhost1_dma_mask = 0xffffffffUL;

static struct resource msp_usbhost1_resources[] = {
	[0] = { /* EHCI-HS operational and capabilities registers */
		.start	= MSP_USB1_HS_START,
		.end	= MSP_USB1_HS_END,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= MSP_INT_USB,
		.end	= MSP_INT_USB,
		.flags	= IORESOURCE_IRQ,
	},
	[2] = { /* MSBus-to-AMBA bridge register space */
		.start	= MSP_USB1_MAB_START,
		.end	= MSP_USB1_MAB_END,
		.flags	= IORESOURCE_MEM,
	},
	[3] = { /* Identification and general hardware parameters */
		.start	= MSP_USB1_ID_START,
		.end	= MSP_USB1_ID_END,
		.flags	= IORESOURCE_MEM,
	},
};

static struct mspusb_device msp_usbhost1_device = {
	.dev	= {
		.name	= "pmcmsp-ehci",
		.id	= 1,
		.dev	= {
			.dma_mask = &msp_usbhost1_dma_mask,
			.coherent_dma_mask = 0xffffffffUL,
		},
		.num_resources	= ARRAY_SIZE(msp_usbhost1_resources),
		.resource	= msp_usbhost1_resources,
	},
	},
	.num_resources 	= ARRAY_SIZE(msp_usbhost_resources),
	.resource	= msp_usbhost_resources,
};
};
#endif /* CONFIG_MSP_HAS_DUAL_USB */
#endif /* CONFIG_USB_EHCI_HCD */
#endif /* CONFIG_USB_EHCI_HCD */


#if defined(CONFIG_USB_GADGET)
#if defined(CONFIG_USB_GADGET)
static struct resource msp_usbdev_resources [] = {
static struct resource msp_usbdev0_resources[] = {
	[0] = {
	[0] = { /* EHCI-HS operational and capabilities registers */
		.start	= MSP_USB_BASE,
		.start  = MSP_USB0_HS_START,
		.end	= MSP_USB_BASE_END,
		.end    = MSP_USB0_HS_END,
		.flags  = IORESOURCE_MEM,
		.flags  = IORESOURCE_MEM,
	},
	},
	[1] = {
	[1] = {
@@ -75,76 +130,134 @@ static struct resource msp_usbdev_resources [] = {
		.end    = MSP_INT_USB,
		.end    = MSP_INT_USB,
		.flags  = IORESOURCE_IRQ,
		.flags  = IORESOURCE_IRQ,
	},
	},
	[2] = { /* MSBus-to-AMBA bridge register space */
		.start	= MSP_USB0_MAB_START,
		.end	= MSP_USB0_MAB_END,
		.flags	= IORESOURCE_MEM,
	},
	[3] = { /* Identification and general hardware parameters */
		.start	= MSP_USB0_ID_START,
		.end	= MSP_USB0_ID_END,
		.flags	= IORESOURCE_MEM,
	},
};
};


static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32);
static u64 msp_usbdev_dma_mask = 0xffffffffUL;


static struct platform_device msp_usbdev_device = {
/* This may need to be converted to a mspusb_device, too. */
static struct mspusb_device msp_usbdev0_device = {
	.dev	= {
		.name	= "msp71xx_udc",
		.name	= "msp71xx_udc",
		.id	= 0,
		.id	= 0,
		.dev	= {
		.dev	= {
			.dma_mask = &msp_usbdev_dma_mask,
			.dma_mask = &msp_usbdev_dma_mask,
		.coherent_dma_mask = DMA_BIT_MASK(32),
			.coherent_dma_mask = 0xffffffffUL,
		},
		.num_resources  = ARRAY_SIZE(msp_usbdev0_resources),
		.resource       = msp_usbdev0_resources,
	},
	},
	.num_resources	= ARRAY_SIZE(msp_usbdev_resources),
	.resource	= msp_usbdev_resources,
};
};
#endif /* CONFIG_USB_GADGET */


#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
#ifdef CONFIG_MSP_HAS_DUAL_USB
static struct platform_device *msp_devs[1];
static struct resource msp_usbdev1_resources[] = {
#endif
	[0] = { /* EHCI-HS operational and capabilities registers */
		.start  = MSP_USB1_HS_START,
		.end    = MSP_USB1_HS_END,
		.flags  = IORESOURCE_MEM,
	},
	[1] = {
		.start  = MSP_INT_USB,
		.end    = MSP_INT_USB,
		.flags  = IORESOURCE_IRQ,
	},
	[2] = { /* MSBus-to-AMBA bridge register space */
		.start	= MSP_USB1_MAB_START,
		.end	= MSP_USB1_MAB_END,
		.flags	= IORESOURCE_MEM,
	},
	[3] = { /* Identification and general hardware parameters */
		.start	= MSP_USB1_ID_START,
		.end	= MSP_USB1_ID_END,
		.flags	= IORESOURCE_MEM,
	},
};

/* This may need to be converted to a mspusb_device, too. */
static struct mspusb_device msp_usbdev1_device = {
	.dev	= {
		.name	= "msp71xx_udc",
		.id	= 0,
		.dev	= {
			.dma_mask = &msp_usbdev_dma_mask,
			.coherent_dma_mask = 0xffffffffUL,
		},
		.num_resources  = ARRAY_SIZE(msp_usbdev1_resources),
		.resource       = msp_usbdev1_resources,
	},
};


#endif /* CONFIG_MSP_HAS_DUAL_USB */
#endif /* CONFIG_USB_GADGET */


static int __init msp_usb_setup(void)
static int __init msp_usb_setup(void)
{
{
#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
	char		*strp;
	char		*strp;
	char		envstr[32];
	char		envstr[32];
	unsigned int val = 0;
	struct platform_device *msp_devs[NUM_USB_DEVS];
	int result = 0;
	unsigned int val;


	/* construct environment name usbmode */
	/* set usbmode <host/device> as pmon environment var */
	/*
	/*
	 * construct environment name usbmode
	 * Could this perhaps be integrated into the "features" env var?
	 * set usbmode <host/device> as pmon environment var
	 * Use the features key "U", and follow with "H" for host-mode,
	 * "D" for device-mode.  If it works for Ethernet, why not USB...
	 *  -- hammtrev, 2007/03/22
	 */
	 */
	snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
	snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");


#if defined(CONFIG_USB_EHCI_HCD)
	/* set default host mode */
	/* default to host mode */
	val = 1;
	val = 1;
#endif


	/* get environment string */
	/* get environment string */
	strp = prom_getenv((char *)&envstr[0]);
	strp = prom_getenv((char *)&envstr[0]);
	if (strp) {
	if (strp) {
		/* compare string */
		if (!strcmp(strp, "device"))
		if (!strcmp(strp, "device"))
			val = 0;
			val = 0;
	}
	}


	if (val) {
	if (val) {
#if defined(CONFIG_USB_EHCI_HCD)
#if defined(CONFIG_USB_EHCI_HCD)
		/* get host mode device */
		msp_devs[0] = &msp_usbhost0_device.dev;
		msp_devs[0] = &msp_usbhost_device;
		ppfinit("platform add USB HOST done %s.\n", msp_devs[0]->name);
		ppfinit("platform add USB HOST done %s.\n",
#ifdef CONFIG_MSP_HAS_DUAL_USB
			    msp_devs[0]->name);
		msp_devs[1] = &msp_usbhost1_device.dev;

		ppfinit("platform add USB HOST done %s.\n", msp_devs[1]->name);
		result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
#endif
#else
		ppfinit("%s: echi_hcd not supported\n", __FILE__);
#endif  /* CONFIG_USB_EHCI_HCD */
#endif  /* CONFIG_USB_EHCI_HCD */
	}
	} else {
#if defined(CONFIG_USB_GADGET)
#if defined(CONFIG_USB_GADGET)
	else {
		/* get device mode structure */
		/* get device mode structure */
		msp_devs[0] = &msp_usbdev_device;
		msp_devs[0] = &msp_usbdev0_device.dev;
		ppfinit("platform add USB DEVICE done %s.\n",
		ppfinit("platform add USB DEVICE done %s.\n"
			    msp_devs[0]->name);
					, msp_devs[0]->name);

#ifdef CONFIG_MSP_HAS_DUAL_USB
		result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
		msp_devs[1] = &msp_usbdev1_device.dev;
	}
		ppfinit("platform add USB DEVICE done %s.\n"
					, msp_devs[1]->name);
#endif
#else
		ppfinit("%s: usb_gadget not supported\n", __FILE__);
#endif  /* CONFIG_USB_GADGET */
#endif  /* CONFIG_USB_GADGET */
#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */
	}
	/* add device */
	platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));


	return result;
	return 0;
}
}


subsys_initcall(msp_usb_setup);
subsys_initcall(msp_usb_setup);
#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */