ehci-omap.c revision 6c984b066d84bb6e8f5a739ffb1dc4858df017a3
154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*
24792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar * ehci-omap.c - driver for USBHOST on OMAP3/4 processors
354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
44792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar * Bus Glue for the EHCI controllers in OMAP3/4
54792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar * Tested on several OMAP3 boards, and OMAP4 Pandaboard
654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda * Copyright (C) 2007-2011 Texas Instruments, Inc.
854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	Author: Vikram Pandita <vikram.pandita@ti.com>
94792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar *	Author: Anand Gadiyar <gadiyar@ti.com>
1019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda *	Author: Keshava Munegowda <keshava_mgowda@ti.com>
1154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
1254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Copyright (C) 2009 Nokia Corporation
1354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	Contact: Felipe Balbi <felipe.balbi@nokia.com>
1454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
1554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Based on "ehci-fsl.c" and "ehci-au1xxx.c" ehci glue layers
1654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
1754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * This program is free software; you can redistribute it and/or modify
1854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * it under the terms of the GNU General Public License as published by
1954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * the Free Software Foundation; either version 2 of the License, or
2054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * (at your option) any later version.
2154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
2254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * This program is distributed in the hope that it will be useful,
2354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * but WITHOUT ANY WARRANTY; without even the implied warranty of
2454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * GNU General Public License for more details.
2654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
2754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * You should have received a copy of the GNU General Public License
2854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * along with this program; if not, write to the Free Software
2954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
3054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
3119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda * TODO (last updated Feb 27, 2010):
3254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- add kernel-doc
3354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- enable AUTOIDLE
3454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *	- add suspend/resume
354792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar *	- add HSIC and TLL support
364792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar *	- convert to use hwmod and runtime PM
3754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
3854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
3954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/platform_device.h>
405a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
415aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta#include <linux/usb/ulpi.h>
42c76f782cb3cfffc1fd4233e11f3116655fa0fcd2Thomas Weber#include <plat/usb.h>
436e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda#include <linux/regulator/consumer.h>
446c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda#include <linux/pm_runtime.h>
4554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
4654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* EHCI Register Set */
47572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar#define EHCI_INSNREG04					(0xA0)
48572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar#define EHCI_INSNREG04_DISABLE_UNSUSPEND		(1 << 5)
4954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI				(0xA4)
5054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_CONTROL_SHIFT		31
5154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_PORTSEL_SHIFT		24
5254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_OPSEL_SHIFT			22
5354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_REGADD_SHIFT		16
5454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT		8
5554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define	EHCI_INSNREG05_ULPI_WRDATA_SHIFT		0
5654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
5719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda/*-------------------------------------------------------------------------*/
584792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar
5919403165c272cc4ed00c97973e7271714b009708Keshava Munegowdastatic const struct hc_driver ehci_omap_hc_driver;
604792a15bf0f388838c3e16636f961c99bc2f3572Anand Gadiyar
61a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar
6219403165c272cc4ed00c97973e7271714b009708Keshava Munegowdastatic inline void ehci_write(void __iomem *base, u32 reg, u32 val)
6354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
6454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	__raw_writel(val, base + reg);
6554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
6654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
6719403165c272cc4ed00c97973e7271714b009708Keshava Munegowdastatic inline u32 ehci_read(void __iomem *base, u32 reg)
6854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
6954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return __raw_readl(base + reg);
7054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
7154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
7219403165c272cc4ed00c97973e7271714b009708Keshava Munegowdastatic void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port)
735aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta{
7419403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct usb_hcd	*hcd = dev_get_drvdata(&pdev->dev);
755aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
765aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta	unsigned reg = 0;
775aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta
785aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta	reg = ULPI_FUNC_CTRL_RESET
795aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		/* FUNCTION_CTRL_SET register */
805aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		| (ULPI_SET(ULPI_FUNC_CTRL) << EHCI_INSNREG05_ULPI_REGADD_SHIFT)
815aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		/* Write */
825aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		| (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT)
835aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		/* PORTn */
845aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		| ((port + 1) << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT)
855aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		/* start ULPI access*/
865aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		| (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT);
875aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta
8819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	ehci_write(hcd->regs, EHCI_INSNREG05_ULPI, reg);
895aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta
905aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta	/* Wait for ULPI access completion */
9119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	while ((ehci_read(hcd->regs, EHCI_INSNREG05_ULPI)
925aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta			& (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) {
935aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		cpu_relax();
945aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta
955aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		if (time_after(jiffies, timeout)) {
9619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda			dev_dbg(&pdev->dev, "phy reset operation timed out\n");
975aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta			break;
985aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta		}
995aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta	}
1005aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta}
1015aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta
102d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Leistatic void disable_put_regulator(
103d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei		struct ehci_hcd_omap_platform_data *pdata)
104d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei{
105d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	int i;
106d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei
107d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
108d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei		if (pdata->regulator[i]) {
109d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei			regulator_disable(pdata->regulator[i]);
110d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei			regulator_put(pdata->regulator[i]);
111d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei		}
112d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	}
113d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei}
11454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
11554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* configure so an HC device and id are always provided */
11654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* always called with process context; sleeping is OK */
11754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
11854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/**
11954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci_hcd_omap_probe - initialize TI-based HCDs
12054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
12154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Allocates basic resources for this USB host controller, and
12254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * then invokes the start() method for the HCD associated with it
12354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * through the hotplug entry's driver_data.
12454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
12554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int ehci_hcd_omap_probe(struct platform_device *pdev)
12654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
12719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct device				*dev = &pdev->dev;
12819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct ehci_hcd_omap_platform_data	*pdata = dev->platform_data;
12919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct resource				*res;
13019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct usb_hcd				*hcd;
13119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	void __iomem				*regs;
13219403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct ehci_hcd				*omap_ehci;
13319403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	int					ret = -ENODEV;
13419403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	int					irq;
1356e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda	int					i;
1366e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda	char					supply[7];
13754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
13819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (usb_disabled())
13919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		return -ENODEV;
14054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
14119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (!dev->parent) {
14219403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		dev_err(dev, "Missing parent device\n");
14319403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		return -ENODEV;
14454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
14554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
14619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	irq = platform_get_irq_byname(pdev, "ehci-irq");
14719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (irq < 0) {
14819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		dev_err(dev, "EHCI irq failed\n");
14919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		return -ENODEV;
15019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	}
15154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
15219403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	res =  platform_get_resource_byname(pdev,
15319403165c272cc4ed00c97973e7271714b009708Keshava Munegowda				IORESOURCE_MEM, "ehci");
15419403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (!res) {
15519403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		dev_err(dev, "UHH EHCI get resource failed\n");
15619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		return -ENODEV;
15719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	}
15819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda
15919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	regs = ioremap(res->start, resource_size(res));
16019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (!regs) {
16119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		dev_err(dev, "UHH EHCI ioremap failed\n");
16219403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		return -ENOMEM;
16354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
16454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
16519403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	hcd = usb_create_hcd(&ehci_omap_hc_driver, dev,
16619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda			dev_name(dev));
16754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (!hcd) {
16819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		dev_err(dev, "failed to create hcd with err %d\n", ret);
16954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		ret = -ENOMEM;
17019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		goto err_io;
17154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
17254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
17354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	hcd->rsrc_start = res->start;
17454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	hcd->rsrc_len = resource_size(res);
17519403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	hcd->regs = regs;
17654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
1776e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda	/* get ehci regulator and enable */
1786e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
1796e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) {
1806e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda			pdata->regulator[i] = NULL;
1816e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda			continue;
1826e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		}
1836e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		snprintf(supply, sizeof(supply), "hsusb%d", i);
1846e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		pdata->regulator[i] = regulator_get(dev, supply);
1856e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		if (IS_ERR(pdata->regulator[i])) {
1866e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda			pdata->regulator[i] = NULL;
1876e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda			dev_dbg(dev,
1886e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda			"failed to get ehci port%d regulator\n", i);
1896e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		} else {
1906e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda			regulator_enable(pdata->regulator[i]);
1916e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda		}
1926e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda	}
1936e3d4bec6b1e0829ed8b23be750762255f225019Keshava Munegowda
1946c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda	pm_runtime_enable(dev);
1956c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda	pm_runtime_get_sync(dev);
19654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
19719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	/*
19819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * An undocumented "feature" in the OMAP3 EHCI controller,
19919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * causes suspended ports to be taken out of suspend when
20019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * the USBCMD.Run/Stop bit is cleared (for example when
20119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * we do ehci_bus_suspend).
20219403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * This breaks suspend-resume if the root-hub is allowed
20319403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * to suspend. Writing 1 to this undocumented register bit
20419403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 * disables this feature and restores normal behavior.
20519403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	 */
20619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	ehci_write(regs, EHCI_INSNREG04,
20719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda				EHCI_INSNREG04_DISABLE_UNSUSPEND);
20854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
20919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	/* Soft reset the PHY using PHY reset command over ULPI */
21019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (pdata->port_mode[0] == OMAP_EHCI_PORT_MODE_PHY)
21119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		omap_ehci_soft_phy_reset(pdev, 0);
21219403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	if (pdata->port_mode[1] == OMAP_EHCI_PORT_MODE_PHY)
21319403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		omap_ehci_soft_phy_reset(pdev, 1);
214881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta
21519403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	omap_ehci = hcd_to_ehci(hcd);
21619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	omap_ehci->sbrn = 0x20;
21754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
21819403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	/* we know this is the memory we want, no need to ioremap again */
21919403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	omap_ehci->caps = hcd->regs;
22019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	omap_ehci->regs = hcd->regs
221c430131a02d677aa708f56342c1565edfdacb3c0Jan Andersson		+ HC_LENGTH(ehci, readl(&omap_ehci->caps->hc_capbase));
22254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
22319403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	dbg_hcs_params(omap_ehci, "reset");
22419403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	dbg_hcc_params(omap_ehci, "reset");
225bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar
22654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/* cache this readonly data; minimize chip reads */
22719403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params);
22854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
229b5dd18d8747010e3f3eb1cc76a49f94291938559Yong Zhang	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
23054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (ret) {
23119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda		dev_err(dev, "failed to add hcd with err %d\n", ret);
23254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		goto err_add_hcd;
23354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
23454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
235289621c31bffb743e4007f6332b9004cdd080644Ajay Kumar Gupta	/* root ports should always stay powered */
23619403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	ehci_port_power(omap_ehci, 1);
237289621c31bffb743e4007f6332b9004cdd080644Ajay Kumar Gupta
23854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return 0;
23954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
24054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_add_hcd:
241d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	disable_put_regulator(pdata);
2426c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda	pm_runtime_put_sync(dev);
24354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
24419403165c272cc4ed00c97973e7271714b009708Keshava Munegowdaerr_io:
245d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	iounmap(regs);
24654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return ret;
24754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
24854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
24954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
25054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/**
25154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs
25254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * @pdev: USB Host Controller being removed
25354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi *
25454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking
25554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * the HCD's stop() method.  It is always called from a thread
25654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * context, normally "rmmod", "apmd", or something similar.
25754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */
25854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int ehci_hcd_omap_remove(struct platform_device *pdev)
25954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
26019403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct device *dev	= &pdev->dev;
26119403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct usb_hcd *hcd	= dev_get_drvdata(dev);
26254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
26354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	usb_remove_hcd(hcd);
264d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	disable_put_regulator(dev->platform_data);
265d4aefec5daf51ebda90ebf0989598c206cf8e640Ming Lei	iounmap(hcd->regs);
26654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	usb_put_hcd(hcd);
2676c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda	pm_runtime_put_sync(dev);
2686c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda	pm_runtime_disable(dev);
2696c984b066d84bb6e8f5a739ffb1dc4858df017a3Keshava Munegowda
27054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	return 0;
27154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
27254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
27354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic void ehci_hcd_omap_shutdown(struct platform_device *pdev)
27454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{
27519403165c272cc4ed00c97973e7271714b009708Keshava Munegowda	struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev);
27654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
27754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	if (hcd->driver->shutdown)
27854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		hcd->driver->shutdown(hcd);
27954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}
28054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
28154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic struct platform_driver ehci_hcd_omap_driver = {
28254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.probe			= ehci_hcd_omap_probe,
28354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.remove			= ehci_hcd_omap_remove,
28454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.shutdown		= ehci_hcd_omap_shutdown,
28554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*.suspend		= ehci_hcd_omap_suspend, */
28654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*.resume		= ehci_hcd_omap_resume, */
28754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.driver = {
28854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi		.name		= "ehci-omap",
28954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	}
29054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi};
29154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
29254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/
29354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
29454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic const struct hc_driver ehci_omap_hc_driver = {
29554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.description		= hcd_name,
29654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.product_desc		= "OMAP-EHCI Host Controller",
29754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.hcd_priv_size		= sizeof(struct ehci_hcd),
29854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
29954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
30054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * generic hardware linkage
30154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
30254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.irq			= ehci_irq,
30354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.flags			= HCD_MEMORY | HCD_USB2,
30454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
30554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
30654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * basic lifecycle operations
30754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
30854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.reset			= ehci_init,
30954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.start			= ehci_run,
31054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.stop			= ehci_stop,
31154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.shutdown		= ehci_shutdown,
31254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
31354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
31454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * managing i/o requests and associated device resources
31554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
31654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.urb_enqueue		= ehci_urb_enqueue,
31754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.urb_dequeue		= ehci_urb_dequeue,
31854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.endpoint_disable	= ehci_endpoint_disable,
31954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.endpoint_reset		= ehci_endpoint_reset,
32054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
32154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
32254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * scheduling support
32354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
32454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.get_frame_number	= ehci_get_frame,
32554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
32654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	/*
32754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 * root hub support
32854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	 */
32954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.hub_status_data	= ehci_hub_status_data,
33054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.hub_control		= ehci_hub_control,
33154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.bus_suspend		= ehci_bus_suspend,
33254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.bus_resume		= ehci_bus_resume,
33354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
33454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
33554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi};
33654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
33754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_ALIAS("platform:omap-ehci");
33854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_AUTHOR("Texas Instruments, Inc.");
33954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
34054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi
341