ehci-omap.c revision 5a0e3ad6af8660be21ca98a971cd00f331318c05
154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*
254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci-omap.c - driver for USBHOST on OMAP 34xx processor
354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller
554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Tested on OMAP3430 ES2.0 SDP
654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Copyright (C) 2007-2008 Texas Instruments, Inc.
854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	Author: Vikram Pandita <vikram.pandita@ti.com>
954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
1054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Copyright (C) 2009 Nokia Corporation
1154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	Contact: Felipe Balbi <felipe.balbi@nokia.com>
1254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
1354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Based on "ehci-fsl.c" and "ehci-au1xxx.c" ehci glue layers
1454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
1554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * This program is free software; you can redistribute it and/or modify
1654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * it under the terms of the GNU General Public License as published by
1754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * the Free Software Foundation; either version 2 of the License, or
1854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * (at your option) any later version.
1954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
2054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * This program is distributed in the hope that it will be useful,
2154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * but WITHOUT ANY WARRANTY; without even the implied warranty of
2254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * GNU General Public License for more details.
2454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
2554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * You should have received a copy of the GNU General Public License
2654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * along with this program; if not, write to the Free Software
2754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
2854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
29bdee2d8432f5af5af953896182a59ec1c5d6fa3aAnand Gadiyar * TODO (last updated Feb 12, 2010):
3054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- add kernel-doc
3154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- enable AUTOIDLE
3254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- add suspend/resume
3354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- move workarounds to board-files
3454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
3554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
3654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/platform_device.h>
3754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/clk.h>
3854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/gpio.h>
39881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta#include <linux/regulator/consumer.h>
405a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
41c76f782cb3cfffc1fd4233e11f3116655fa0fcd2Thomas Weber#include <plat/usb.h>
4254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
4354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*
4454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES
4554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	Use ehci_omap_readl()/ehci_omap_writel() functions
4654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
4754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
4854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* TLL Register Set */
4954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_REVISION				(0x00)
5054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSCONFIG				(0x10)
5154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8)
5254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3)
5354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2)
5454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1)
5554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSCONFIG_AUTOIDLE			(1 << 0)
5654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
5754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSSTATUS				(0x14)
5854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_SYSSTATUS_RESETDONE			(1 << 0)
5954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
6054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_IRQSTATUS				(0x18)
6154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_USBTLL_IRQENABLE				(0x1C)
6254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
6354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_SHARED_CONF				(0x30)
6454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN		(1 << 6)
6554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN		(1 << 5)
6654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_SHARED_CONF_USB_DIVRATION		(1 << 2)
6754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_SHARED_CONF_FCLK_REQ			(1 << 1)
6854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_SHARED_CONF_FCLK_IS_ON			(1 << 0)
6954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
7054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_CHANNEL_CONF(num)			(0x040 + 0x004 * num)
7154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11)
7254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE		(1 << 10)
7354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE		(1 << 9)
7454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE		(1 << 8)
7554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_CHANNEL_CONF_CHANEN			(1 << 0)
7654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
7754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_FUNCTION_CTRL(num)		(0x804 + 0x100 * num)
7854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_INTERFACE_CTRL(num)		(0x807 + 0x100 * num)
7954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_OTG_CTRL(num)			(0x80A + 0x100 * num)
8054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_INT_EN_RISE(num)			(0x80D + 0x100 * num)
8154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_INT_EN_FALL(num)			(0x810 + 0x100 * num)
8254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_INT_STATUS(num)			(0x813 + 0x100 * num)
8354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_INT_LATCH(num)			(0x814 + 0x100 * num)
8454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_DEBUG(num)			(0x815 + 0x100 * num)
8554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_TLL_ULPI_SCRATCH_REGISTER(num)		(0x816 + 0x100 * num)
8654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
8754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_COUNT				3
8854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_1_EN_MASK			(1 << 1)
8954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_2_EN_MASK			(1 << 2)
9054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_3_EN_MASK			(1 << 4)
9154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
9254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* UHH Register Set */
9354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_REVISION				(0x00)
9454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG				(0x10)
9554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12)
9654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8)
9754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3)
9854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2)
9954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1)
10054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSCONFIG_AUTOIDLE			(1 << 0)
10154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
10254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_SYSSTATUS				(0x14)
10354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_HOSTCONFIG				(0x40)
10454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_HOSTCONFIG_ULPI_BYPASS			(1 << 0)
10554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		(1 << 0)
10654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS		(1 << 11)
10754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS		(1 << 12)
10854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2)
10954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3)
11054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4)
11154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN		(1 << 5)
11254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS		(1 << 8)
11354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS		(1 << 9)
11454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS		(1 << 10)
11554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
11654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	OMAP_UHH_DEBUG_CSR				(0x44)
11754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
11854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* EHCI Register Set */
11954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI				(0xA4)
12054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_CONTROL_SHIFT		31
12154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_PORTSEL_SHIFT		24
12254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_OPSEL_SHIFT			22
12354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_REGADD_SHIFT		16
12454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT		8
12554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_WRDATA_SHIFT		0
12654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
12754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
12854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
12954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val)
13054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
13154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	__raw_writel(val, base + reg);
13254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
13354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
13454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline u32 ehci_omap_readl(void __iomem *base, u32 reg)
13554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
13654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return __raw_readl(base + reg);
13754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
13854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
13954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline void ehci_omap_writeb(void __iomem *base, u8 reg, u8 val)
14054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
14154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	__raw_writeb(val, base + reg);
14254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
14354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
14454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline u8 ehci_omap_readb(void __iomem *base, u8 reg)
14554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
14654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return __raw_readb(base + reg);
14754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
14854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
14954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
15054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
15154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistruct ehci_hcd_omap {
15254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct ehci_hcd		*ehci;
15354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct device		*dev;
15454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
15554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct clk		*usbhost_ick;
15654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct clk		*usbhost2_120m_fck;
15754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct clk		*usbhost1_48m_fck;
15854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct clk		*usbtll_fck;
15954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct clk		*usbtll_ick;
16054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
16154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* FIXME the following two workarounds are
16254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * board specific not silicon-specific so these
16354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * should be moved to board-file instead.
16454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 *
16554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * Maybe someone from TI will know better which
16654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * board is affected and needs the workarounds
16754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * to be applied
16854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
16954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
17054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* gpio for resetting phy */
17154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	int			reset_gpio_port[OMAP3_HS_USB_PORTS];
17254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
17354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* phy reset workaround */
17454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	int			phy_reset;
17554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
17654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* desired phy_mode: TLL, PHY */
17754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	enum ehci_hcd_omap_mode	port_mode[OMAP3_HS_USB_PORTS];
17854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
17954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	void __iomem		*uhh_base;
18054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	void __iomem		*tll_base;
18154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	void __iomem		*ehci_base;
182881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta
183881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	/* Regulators for USB PHYs.
184881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	 * Each PHY can have a seperate regulator.
185881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	 */
186881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	struct regulator        *regulator[OMAP3_HS_USB_PORTS];
18754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi};
18854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
18954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
19054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
19154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask)
19254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
19354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	unsigned reg;
19454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	int i;
19554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
19654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Program the 3 TLL channels upfront */
19754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {
19854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
19954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
20054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		/* Disable AutoIdle, BitStuffing and use SDR Mode */
20154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
20254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
20354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
20454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
20554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
20654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
20754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Program Common TLL register */
20854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF);
20954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
21054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_TLL_SHARED_CONF_USB_DIVRATION
21154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN);
21254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
21354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
21454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
21554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
21654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Enable channels now */
21754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {
21854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
21954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
22054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		/* Enable only the reg that is needed */
22154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (!(tll_channel_mask & 1<<i))
22254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			continue;
22354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
22454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
22554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
22654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
22754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ehci_omap_writeb(omap->tll_base,
22854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
22954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(omap->dev, "ULPI_SCRATCH_REG[ch=%d]= 0x%02x\n",
23054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				i+1, ehci_omap_readb(omap->tll_base,
23154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				OMAP_TLL_ULPI_SCRATCH_REGISTER(i)));
23254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
23354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
23454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
23554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
23654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
23754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* omap_start_ehc
23854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- Start the TI USBHOST controller
23954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
24054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
24154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
24254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
24354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	u8 tll_ch_mask = 0;
24454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	unsigned reg = 0;
24554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	int ret = 0;
24654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
24754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	dev_dbg(omap->dev, "starting TI EHCI USB Controller\n");
24854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
24954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Enable Clocks for USBHOST */
25054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick");
25154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (IS_ERR(omap->usbhost_ick)) {
25254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret =  PTR_ERR(omap->usbhost_ick);
25354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_host_ick;
25454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
25554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_enable(omap->usbhost_ick);
25654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
25754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck");
25854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (IS_ERR(omap->usbhost2_120m_fck)) {
25954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = PTR_ERR(omap->usbhost2_120m_fck);
26054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_host_120m_fck;
26154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
26254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_enable(omap->usbhost2_120m_fck);
26354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
26454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck");
26554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (IS_ERR(omap->usbhost1_48m_fck)) {
26654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = PTR_ERR(omap->usbhost1_48m_fck);
26754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_host_48m_fck;
26854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
26954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_enable(omap->usbhost1_48m_fck);
27054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
27154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->phy_reset) {
27254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		/* Refer: ISSUE1 */
27354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[0])) {
27454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_request(omap->reset_gpio_port[0],
27554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi						"USB1 PHY reset");
27654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_direction_output(omap->reset_gpio_port[0], 0);
27754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		}
27854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
27954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[1])) {
28054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_request(omap->reset_gpio_port[1],
28154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi						"USB2 PHY reset");
28254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_direction_output(omap->reset_gpio_port[1], 0);
28354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		}
28454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
28554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		/* Hold the PHY in RESET for enough time till DIR is high */
28654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		udelay(10);
28754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
28854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
28954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Configure TLL for 60Mhz clk for ULPI */
29054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck");
29154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (IS_ERR(omap->usbtll_fck)) {
29254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = PTR_ERR(omap->usbtll_fck);
29354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_tll_fck;
29454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
29554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_enable(omap->usbtll_fck);
29654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
29754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick");
29854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (IS_ERR(omap->usbtll_ick)) {
29954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = PTR_ERR(omap->usbtll_ick);
30054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_tll_ick;
30154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
30254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_enable(omap->usbtll_ick);
30354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
30454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* perform TLL soft reset, and wait until reset is complete */
30554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
30654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			OMAP_USBTLL_SYSCONFIG_SOFTRESET);
30754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
30854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Wait for TLL reset to complete */
30954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
31054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			& OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
31154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		cpu_relax();
31254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
31354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (time_after(jiffies, timeout)) {
31454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			dev_dbg(omap->dev, "operation timed out\n");
31554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			ret = -EINVAL;
31654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			goto err_sys_status;
31754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		}
31854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
31954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
32054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	dev_dbg(omap->dev, "TLL RESET DONE\n");
32154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
32254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* (1<<3) = no idle mode only for initial debugging */
32354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
32454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
32554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
32654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			OMAP_USBTLL_SYSCONFIG_CACTIVITY);
32754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
32854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
32954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Put UHH in NoIdle/NoStandby mode */
33054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG);
33154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
33254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_UHH_SYSCONFIG_SIDLEMODE
33354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_UHH_SYSCONFIG_CACTIVITY
33454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_UHH_SYSCONFIG_MIDLEMODE);
33554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
33654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
33754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
33854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
33954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
34054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
34154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* setup ULPI bypass and burst configurations */
34254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
34354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
34454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
34554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
34654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
34754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
34854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS;
34954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
35054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
35154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
35254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
35354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
35454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Bypass the TLL module for PHY mode operation */
35554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 if (omap_rev() <= OMAP3430_REV_ES2_1) {
35654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1 \n");
35754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
35854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			(omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
35954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				(omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
36054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
36154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		else
36254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
36354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	} else {
36454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n");
36554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
36654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
36754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
36854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
36954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
37054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
37154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
37254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
37354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
37454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
37554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)
37654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
37754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
37854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
37954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
38054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
38154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
38254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
38354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
38454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
38554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ||
38654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		(omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ||
38754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			(omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) {
38854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
38954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
39054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK;
39154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
39254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK;
39354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
39454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK;
39554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
39654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		/* Enable UTMI mode for required TLL channels */
39754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		omap_usb_utmi_init(omap, tll_ch_mask);
39854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
39954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
40054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->phy_reset) {
40154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		/* Refer ISSUE1:
40254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		 * Hold the PHY in RESET for enough time till
40354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		 * PHY is settled and ready
40454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		 */
40554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		udelay(10);
40654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
40754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[0]))
40854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_set_value(omap->reset_gpio_port[0], 1);
40954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
41054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[1]))
41154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_set_value(omap->reset_gpio_port[1], 1);
41254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
41354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
41454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return 0;
41554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
41654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_sys_status:
41754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_disable(omap->usbtll_ick);
41854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_put(omap->usbtll_ick);
41954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
42054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_tll_ick:
42154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_disable(omap->usbtll_fck);
42254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_put(omap->usbtll_fck);
42354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
42454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_tll_fck:
42554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_disable(omap->usbhost1_48m_fck);
42654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_put(omap->usbhost1_48m_fck);
42754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
42854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->phy_reset) {
42954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[0]))
43054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_free(omap->reset_gpio_port[0]);
43154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
43254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[1]))
43354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_free(omap->reset_gpio_port[1]);
43454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
43554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
43654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_host_48m_fck:
43754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_disable(omap->usbhost2_120m_fck);
43854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_put(omap->usbhost2_120m_fck);
43954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
44054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_host_120m_fck:
44154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_disable(omap->usbhost_ick);
44254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	clk_put(omap->usbhost_ick);
44354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
44454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_host_ick:
44554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return ret;
44654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
44754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
44854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
44954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
45054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	unsigned long timeout = jiffies + msecs_to_jiffies(100);
45154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
45254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n");
45354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
45454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* Reset OMAP modules for insmod/rmmod to work */
45554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG,
45654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			OMAP_UHH_SYSCONFIG_SOFTRESET);
45754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
45854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				& (1 << 0))) {
45954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		cpu_relax();
46054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
46154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (time_after(jiffies, timeout))
46254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			dev_dbg(omap->dev, "operation timed out\n");
46354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
46454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
46554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
46654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				& (1 << 1))) {
46754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		cpu_relax();
46854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
46954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (time_after(jiffies, timeout))
47054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			dev_dbg(omap->dev, "operation timed out\n");
47154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
47254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
47354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
47454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				& (1 << 2))) {
47554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		cpu_relax();
47654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
47754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (time_after(jiffies, timeout))
47854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			dev_dbg(omap->dev, "operation timed out\n");
47954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
48054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
48154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
48254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
48354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
48454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi				& (1 << 0))) {
48554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		cpu_relax();
48654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
48754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (time_after(jiffies, timeout))
48854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			dev_dbg(omap->dev, "operation timed out\n");
48954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
49054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
49154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->usbtll_fck != NULL) {
49254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_disable(omap->usbtll_fck);
49354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_put(omap->usbtll_fck);
49454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		omap->usbtll_fck = NULL;
49554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
49654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
49754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->usbhost_ick != NULL) {
49854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_disable(omap->usbhost_ick);
49954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_put(omap->usbhost_ick);
50054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		omap->usbhost_ick = NULL;
50154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
50254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
50354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->usbhost1_48m_fck != NULL) {
50454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_disable(omap->usbhost1_48m_fck);
50554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_put(omap->usbhost1_48m_fck);
50654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		omap->usbhost1_48m_fck = NULL;
50754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
50854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
50954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->usbhost2_120m_fck != NULL) {
51054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_disable(omap->usbhost2_120m_fck);
51154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_put(omap->usbhost2_120m_fck);
51254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		omap->usbhost2_120m_fck = NULL;
51354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
51454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
51554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->usbtll_ick != NULL) {
51654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_disable(omap->usbtll_ick);
51754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		clk_put(omap->usbtll_ick);
51854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		omap->usbtll_ick = NULL;
51954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
52054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
52154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (omap->phy_reset) {
52254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[0]))
52354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_free(omap->reset_gpio_port[0]);
52454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
52554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		if (gpio_is_valid(omap->reset_gpio_port[1]))
52654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			gpio_free(omap->reset_gpio_port[1]);
52754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
52854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
52954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	dev_dbg(omap->dev, "Clock to USB host has been disabled\n");
53054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
53154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
53254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
53354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
53454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic const struct hc_driver ehci_omap_hc_driver;
53554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
53654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* configure so an HC device and id are always provided */
53754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* always called with process context; sleeping is OK */
53854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
53954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/**
54054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci_hcd_omap_probe - initialize TI-based HCDs
54154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
54254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Allocates basic resources for this USB host controller, and
54354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * then invokes the start() method for the HCD associated with it
54454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * through the hotplug entry's driver_data.
54554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
54654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int ehci_hcd_omap_probe(struct platform_device *pdev)
54754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
54854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
54954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct ehci_hcd_omap *omap;
55054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct resource *res;
55154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct usb_hcd *hcd;
55254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
55354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	int irq = platform_get_irq(pdev, 0);
55454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	int ret = -ENODEV;
555881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	int i;
556881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	char supply[7];
55754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
55854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!pdata) {
55954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(&pdev->dev, "missing platform_data\n");
56054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_pdata;
56154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
56254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
56354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (usb_disabled())
56454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_disabled;
56554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
56654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
56754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!omap) {
56854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = -ENOMEM;
569b2b608090544ecd30a826c32958bca74fb717963Julia Lawall		goto err_disabled;
57054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
57154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
57254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
57354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi			dev_name(&pdev->dev));
57454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!hcd) {
57554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
57654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = -ENOMEM;
57754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_create_hcd;
57854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
57954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
58054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	platform_set_drvdata(pdev, omap);
58154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->dev		= &pdev->dev;
58254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->phy_reset		= pdata->phy_reset;
58354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
58454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
58554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
58654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->port_mode[0]		= pdata->port_mode[0];
58754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->port_mode[1]		= pdata->port_mode[1];
58854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->port_mode[2]		= pdata->port_mode[2];
58954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->ehci		= hcd_to_ehci(hcd);
59054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->ehci->sbrn	= 0x20;
59154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
59254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
59354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
59454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	hcd->rsrc_start = res->start;
59554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	hcd->rsrc_len = resource_size(res);
59654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
59754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
59854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!hcd->regs) {
59954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_err(&pdev->dev, "EHCI ioremap failed\n");
60054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = -ENOMEM;
60154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_ioremap;
60254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
60354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
60454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* we know this is the memory we want, no need to ioremap again */
60554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->ehci->caps = hcd->regs;
60654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->ehci_base = hcd->regs;
60754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
60854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
60954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->uhh_base = ioremap(res->start, resource_size(res));
61054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!omap->uhh_base) {
61154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_err(&pdev->dev, "UHH ioremap failed\n");
61254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = -ENOMEM;
61354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_uhh_ioremap;
61454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
61554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
61654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
61754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->tll_base = ioremap(res->start, resource_size(res));
61854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!omap->tll_base) {
61954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_err(&pdev->dev, "TLL ioremap failed\n");
62054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = -ENOMEM;
62154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_tll_ioremap;
62254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
62354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
624881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	/* get ehci regulator and enable */
625881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
626881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
627881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			omap->regulator[i] = NULL;
628881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			continue;
629881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		}
630881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		snprintf(supply, sizeof(supply), "hsusb%d", i);
631881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		omap->regulator[i] = regulator_get(omap->dev, supply);
632881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		if (IS_ERR(omap->regulator[i]))
633881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			dev_dbg(&pdev->dev,
634881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			"failed to get ehci port%d regulator\n", i);
635881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		else
636881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			regulator_enable(omap->regulator[i]);
637881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	}
638881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta
63954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ret = omap_start_ehc(omap, hcd);
64054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (ret) {
64154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(&pdev->dev, "failed to start ehci\n");
64254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_start;
64354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
64454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
64554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->ehci->regs = hcd->regs
64654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));
64754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
648bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar	dbg_hcs_params(omap->ehci, "reset");
649bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar	dbg_hcc_params(omap->ehci, "reset");
650bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar
65154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* cache this readonly data; minimize chip reads */
65254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);
65354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
65454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
65554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (ret) {
65654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
65754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_add_hcd;
65854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
65954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
66054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return 0;
66154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
66254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_add_hcd:
66354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap_stop_ehc(omap, hcd);
66454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
66554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_start:
666881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
667881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		if (omap->regulator[i]) {
668881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			regulator_disable(omap->regulator[i]);
669881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			regulator_put(omap->regulator[i]);
670881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		}
671881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	}
67254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	iounmap(omap->tll_base);
67354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
67454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_tll_ioremap:
67554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	iounmap(omap->uhh_base);
67654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
67754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_uhh_ioremap:
67854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	iounmap(hcd->regs);
67954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
68054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_ioremap:
68154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	usb_put_hcd(hcd);
68254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
68354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_create_hcd:
684b2b608090544ecd30a826c32958bca74fb717963Julia Lawall	kfree(omap);
68554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_disabled:
68654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_pdata:
68754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return ret;
68854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
68954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
69054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* may be called without controller electrically present */
69154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* may be called with controller, bus, and devices active */
69254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
69354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/**
69454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs
69554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * @pdev: USB Host Controller being removed
69654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
69754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking
69854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * the HCD's stop() method.  It is always called from a thread
69954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * context, normally "rmmod", "apmd", or something similar.
70054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
70154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int ehci_hcd_omap_remove(struct platform_device *pdev)
70254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
70354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct ehci_hcd_omap *omap = platform_get_drvdata(pdev);
70454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct usb_hcd *hcd = ehci_to_hcd(omap->ehci);
705881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	int i;
70654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
70754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	usb_remove_hcd(hcd);
70854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	omap_stop_ehc(omap, hcd);
70954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	iounmap(hcd->regs);
710881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
711881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		if (omap->regulator[i]) {
712881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			regulator_disable(omap->regulator[i]);
713881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta			regulator_put(omap->regulator[i]);
714881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta		}
715881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta	}
71654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	iounmap(omap->tll_base);
71754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	iounmap(omap->uhh_base);
71854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	usb_put_hcd(hcd);
719d3ae8562d43fe2b97d605dd67dc67bf8fa9b956aAjay Kumar Gupta	kfree(omap);
72054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
72154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return 0;
72254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
72354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
72454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic void ehci_hcd_omap_shutdown(struct platform_device *pdev)
72554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
72654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct ehci_hcd_omap *omap = platform_get_drvdata(pdev);
72754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	struct usb_hcd *hcd = ehci_to_hcd(omap->ehci);
72854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
72954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (hcd->driver->shutdown)
73054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		hcd->driver->shutdown(hcd);
73154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
73254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
73354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic struct platform_driver ehci_hcd_omap_driver = {
73454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.probe			= ehci_hcd_omap_probe,
73554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.remove			= ehci_hcd_omap_remove,
73654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.shutdown		= ehci_hcd_omap_shutdown,
73754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*.suspend		= ehci_hcd_omap_suspend, */
73854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*.resume		= ehci_hcd_omap_resume, */
73954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.driver = {
74054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		.name		= "ehci-omap",
74154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
74254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi};
74354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
74454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
74554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
74654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic const struct hc_driver ehci_omap_hc_driver = {
74754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.description		= hcd_name,
74854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.product_desc		= "OMAP-EHCI Host Controller",
74954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.hcd_priv_size		= sizeof(struct ehci_hcd),
75054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
75154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
75254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * generic hardware linkage
75354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
75454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.irq			= ehci_irq,
75554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.flags			= HCD_MEMORY | HCD_USB2,
75654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
75754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
75854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * basic lifecycle operations
75954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
76054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.reset			= ehci_init,
76154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.start			= ehci_run,
76254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.stop			= ehci_stop,
76354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.shutdown		= ehci_shutdown,
76454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
76554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
76654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * managing i/o requests and associated device resources
76754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
76854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.urb_enqueue		= ehci_urb_enqueue,
76954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.urb_dequeue		= ehci_urb_dequeue,
77054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.endpoint_disable	= ehci_endpoint_disable,
77154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.endpoint_reset		= ehci_endpoint_reset,
77254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
77354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
77454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * scheduling support
77554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
77654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.get_frame_number	= ehci_get_frame,
77754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
77854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
77954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * root hub support
78054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
78154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.hub_status_data	= ehci_hub_status_data,
78254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.hub_control		= ehci_hub_control,
78354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.bus_suspend		= ehci_bus_suspend,
78454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.bus_resume		= ehci_bus_resume,
78554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
78654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
78754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi};
78854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
78954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_ALIAS("platform:omap-ehci");
79054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_AUTHOR("Texas Instruments, Inc.");
79154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
79254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
793