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