178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/* 278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * OHCI HCD(Host Controller Driver) for USB. 378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * 478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov *(C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> 578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov *(C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> 678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov *(C) Copyright 2002 Hewlett-Packard Company 778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * 878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * Bus glue for Toshiba Mobile IO(TMIO) Controller's OHCI core 978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * (C) Copyright 2005 Chris Humbert <mahadri-usb@drigon.com> 1078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * (C) Copyright 2007, 2008 Dmitry Baryshkov <dbaryshkov@gmail.com> 1178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * 1278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * This is known to work with the following variants: 1378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * TC6393XB revision 3 (32kB SRAM) 1478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * 1578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * The TMIO's OHCI core DMAs through a small internal buffer that 1678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * is directly addressable by the CPU. 1778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * 1878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * Written from sparse documentation from Toshiba and Sharp's driver 1978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * for the 2.4 kernel, 2078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * usb-ohci-tc6393.c(C) Copyright 2004 Lineo Solutions, Inc. 2178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * 2278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * This program is free software; you can redistribute it and/or modify 2378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * it under the terms of the GNU General Public License version 2 as 2478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * published by the Free Software Foundation. 2578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov */ 2678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 2778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/*#include <linux/fs.h> 2878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/mount.h> 2978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/pagemap.h> 3078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/init.h> 3178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/namei.h> 3278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/sched.h>*/ 3378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/platform_device.h> 3478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/mfd/core.h> 3578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/mfd/tmio.h> 3678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#include <linux/dma-mapping.h> 3778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 3878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/*-------------------------------------------------------------------------*/ 3978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 4078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/* 4178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov * USB Host Controller Configuration Register 4278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov */ 4378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_REVID 0x08 /* b Revision ID */ 4478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_BASE 0x10 /* l USB Control Register Base Address Low */ 4578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_ILME 0x40 /* b Internal Local Memory Enable */ 4678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM 0x4c /* w Power Management */ 4778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_INTC 0x50 /* b INT Control */ 4878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW1L 0x54 /* w Local Memory Window 1 LMADRS Low */ 4978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW1H 0x56 /* w Local Memory Window 1 LMADRS High */ 5078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW1BL 0x58 /* w Local Memory Window 1 Base Address Low */ 5178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW1BH 0x5A /* w Local Memory Window 1 Base Address High */ 5278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW2L 0x5C /* w Local Memory Window 2 LMADRS Low */ 5378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW2H 0x5E /* w Local Memory Window 2 LMADRS High */ 5478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW2BL 0x60 /* w Local Memory Window 2 Base Address Low */ 5578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_LMW2BH 0x62 /* w Local Memory Window 2 Base Address High */ 5678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_MISC 0xFC /* b MISC */ 5778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 5878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_GKEN 0x0001 5978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_CKRNEN 0x0002 6078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_USBPW1 0x0004 6178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_USBPW2 0x0008 6278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_USBPW3 0x0008 6378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_PMEE 0x0100 6478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define CCR_PM_PMES 0x8000 6578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 6678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/*-------------------------------------------------------------------------*/ 6778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 6878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstruct tmio_hcd { 6978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov void __iomem *ccr; 7078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spinlock_t lock; /* protects RMW cycles */ 7178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov}; 7278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 7378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1)) 7478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 7578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/*-------------------------------------------------------------------------*/ 7678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 7778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic void tmio_write_pm(struct platform_device *dev) 7878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 7978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd = platform_get_drvdata(dev); 8078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio = hcd_to_tmio(hcd); 8178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov u16 pm; 8278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov unsigned long flags; 8378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 8478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_lock_irqsave(&tmio->lock, flags); 8578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 8678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov pm = CCR_PM_GKEN | CCR_PM_CKRNEN | 8778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov CCR_PM_PMEE | CCR_PM_PMES; 8878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 8978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite16(pm, tmio->ccr + CCR_PM); 9078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_unlock_irqrestore(&tmio->lock, flags); 9178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 9278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 9378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic void tmio_stop_hc(struct platform_device *dev) 9478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 9578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd = platform_get_drvdata(dev); 9678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct ohci_hcd *ohci = hcd_to_ohci(hcd); 9778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio = hcd_to_tmio(hcd); 9878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov u16 pm; 9978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 10078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov pm = CCR_PM_GKEN | CCR_PM_CKRNEN; 10178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov switch (ohci->num_ports) { 10278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov default: 10378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports); 10478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov case 3: 10578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov pm |= CCR_PM_USBPW3; 10678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov case 2: 10778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov pm |= CCR_PM_USBPW2; 10878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov case 1: 10978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov pm |= CCR_PM_USBPW1; 11078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 11178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite8(0, tmio->ccr + CCR_INTC); 11278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite8(0, tmio->ccr + CCR_ILME); 11378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite16(0, tmio->ccr + CCR_BASE); 11478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite16(0, tmio->ccr + CCR_BASE + 2); 11578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite16(pm, tmio->ccr + CCR_PM); 11678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 11778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 11878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic void tmio_start_hc(struct platform_device *dev) 11978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 12078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd = platform_get_drvdata(dev); 12178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio = hcd_to_tmio(hcd); 12278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov unsigned long base = hcd->rsrc_start; 12378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 12478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_write_pm(dev); 12578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite16(base, tmio->ccr + CCR_BASE); 12678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite16(base >> 16, tmio->ccr + CCR_BASE + 2); 12778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite8(1, tmio->ccr + CCR_ILME); 12878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite8(2, tmio->ccr + CCR_INTC); 12978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 13078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n", 13178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_ioread8(tmio->ccr + CCR_REVID), hcd->rsrc_start, hcd->irq); 13278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 13378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 13478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic int ohci_tmio_start(struct usb_hcd *hcd) 13578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 13678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct ohci_hcd *ohci = hcd_to_ohci(hcd); 13778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov int ret; 13878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 13978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if ((ret = ohci_init(ohci)) < 0) 14078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return ret; 14178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 14278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if ((ret = ohci_run(ohci)) < 0) { 14378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov err("can't start %s", hcd->self.bus_name); 14478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ohci_stop(hcd); 14578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return ret; 14678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 14778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 14878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return 0; 14978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 15078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 15178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic const struct hc_driver ohci_tmio_hc_driver = { 15278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .description = hcd_name, 15378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .product_desc = "TMIO OHCI USB Host Controller", 15478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .hcd_priv_size = sizeof(struct ohci_hcd) + sizeof (struct tmio_hcd), 15578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 15678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov /* generic hardware linkage */ 15778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .irq = ohci_irq, 15878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM, 15978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 16078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov /* basic lifecycle operations */ 16178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .start = ohci_tmio_start, 16278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .stop = ohci_stop, 16378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .shutdown = ohci_shutdown, 16478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 16578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov /* managing i/o requests and associated device resources */ 16678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .urb_enqueue = ohci_urb_enqueue, 16778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .urb_dequeue = ohci_urb_dequeue, 16878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .endpoint_disable = ohci_endpoint_disable, 16978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 17078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov /* scheduling support */ 17178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .get_frame_number = ohci_get_frame, 17278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 17378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov /* root hub support */ 17478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .hub_status_data = ohci_hub_status_data, 17578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .hub_control = ohci_hub_control, 17678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#ifdef CONFIG_PM 17778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .bus_suspend = ohci_bus_suspend, 17878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .bus_resume = ohci_bus_resume, 17978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#endif 18078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .start_port_reset = ohci_start_port_reset, 18178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov}; 18278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 18378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov/*-------------------------------------------------------------------------*/ 18478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic struct platform_driver ohci_hcd_tmio_driver; 18578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 18678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev) 18778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 188944dc03551f6e812c00e586edba84b28c52ffe8cAndres Salomon const struct mfd_cell *cell = mfd_get_cell(dev); 18978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0); 19078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1); 19178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2); 19278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov int irq = platform_get_irq(dev, 0); 19378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio; 19478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct ohci_hcd *ohci; 19578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd; 19678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov int ret; 19778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 19878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (usb_disabled()) 19978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return -ENODEV; 20078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 20178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (!cell) 20278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return -EINVAL; 20378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 204427c4f333474f5447f62387c1fb060e586c1a781Kay Sievers hcd = usb_create_hcd(&ohci_tmio_hc_driver, &dev->dev, dev_name(&dev->dev)); 20578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (!hcd) { 20678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = -ENOMEM; 20778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov goto err_usb_create_hcd; 20878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 20978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 21078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov hcd->rsrc_start = regs->start; 21128f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches hcd->rsrc_len = resource_size(regs); 21278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 21378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio = hcd_to_tmio(hcd); 21478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 21578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_lock_init(&tmio->lock); 21678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 21728f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches tmio->ccr = ioremap(config->start, resource_size(config)); 21878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (!tmio->ccr) { 21978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = -ENOMEM; 22078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov goto err_ioremap_ccr; 22178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 22278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 22378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 22478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (!hcd->regs) { 22578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = -ENOMEM; 22678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov goto err_ioremap_regs; 22778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 22878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 22978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (!dma_declare_coherent_memory(&dev->dev, sram->start, 23078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov sram->start, 23128f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches resource_size(sram), 23278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) { 23378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = -EBUSY; 23478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov goto err_dma_declare; 23578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 23678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 23778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (cell->enable) { 23878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = cell->enable(dev); 23978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (ret) 24078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov goto err_enable; 24178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 24278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 24378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_start_hc(dev); 24478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ohci = hcd_to_ohci(hcd); 24578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ohci_hcd_init(ohci); 24678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 247b5dd18d8747010e3f3eb1cc76a49f94291938559Yong Zhang ret = usb_add_hcd(hcd, irq, 0); 24878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (ret) 24978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov goto err_add_hcd; 25078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 25178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (ret == 0) 25278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return ret; 25378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 25478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov usb_remove_hcd(hcd); 25578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 25678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikoverr_add_hcd: 25778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_stop_hc(dev); 25878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (cell->disable) 25978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov cell->disable(dev); 26078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikoverr_enable: 26178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov dma_release_declared_memory(&dev->dev); 26278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikoverr_dma_declare: 26378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov iounmap(hcd->regs); 26478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikoverr_ioremap_regs: 26578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov iounmap(tmio->ccr); 26678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikoverr_ioremap_ccr: 26778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov usb_put_hcd(hcd); 26878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikoverr_usb_create_hcd: 26978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 27078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return ret; 27178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 27278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 27378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev) 27478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 27578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd = platform_get_drvdata(dev); 27678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio = hcd_to_tmio(hcd); 277944dc03551f6e812c00e586edba84b28c52ffe8cAndres Salomon const struct mfd_cell *cell = mfd_get_cell(dev); 27878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 27978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov usb_remove_hcd(hcd); 28078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_stop_hc(dev); 28178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (cell->disable) 28278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov cell->disable(dev); 28378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov dma_release_declared_memory(&dev->dev); 28478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov iounmap(hcd->regs); 28578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov iounmap(tmio->ccr); 28678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov usb_put_hcd(hcd); 28778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 28878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov platform_set_drvdata(dev, NULL); 28978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 29078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return 0; 29178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 29278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 29378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#ifdef CONFIG_PM 29478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) 29578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 296944dc03551f6e812c00e586edba84b28c52ffe8cAndres Salomon const struct mfd_cell *cell = mfd_get_cell(dev); 29778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd = platform_get_drvdata(dev); 29878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct ohci_hcd *ohci = hcd_to_ohci(hcd); 29978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio = hcd_to_tmio(hcd); 30078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov unsigned long flags; 30178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov u8 misc; 30278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov int ret; 30378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 30478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (time_before(jiffies, ohci->next_statechange)) 30578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov msleep(5); 30678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ohci->next_statechange = jiffies; 30778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 30878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_lock_irqsave(&tmio->lock, flags); 30978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 31078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov misc = tmio_ioread8(tmio->ccr + CCR_MISC); 31178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov misc |= 1 << 3; /* USSUSP */ 31278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite8(misc, tmio->ccr + CCR_MISC); 31378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 31478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_unlock_irqrestore(&tmio->lock, flags); 31578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 31678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (cell->suspend) { 31778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = cell->suspend(dev); 31878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (ret) 31978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return ret; 32078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 32178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return 0; 32278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 32378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 32478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic int ohci_hcd_tmio_drv_resume(struct platform_device *dev) 32578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov{ 326944dc03551f6e812c00e586edba84b28c52ffe8cAndres Salomon const struct mfd_cell *cell = mfd_get_cell(dev); 32778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct usb_hcd *hcd = platform_get_drvdata(dev); 32878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct ohci_hcd *ohci = hcd_to_ohci(hcd); 32978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov struct tmio_hcd *tmio = hcd_to_tmio(hcd); 33078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov unsigned long flags; 33178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov u8 misc; 33278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov int ret; 33378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 33478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (time_before(jiffies, ohci->next_statechange)) 33578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov msleep(5); 33678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ohci->next_statechange = jiffies; 33778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 33878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (cell->resume) { 33978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ret = cell->resume(dev); 34078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov if (ret) 34178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return ret; 34278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov } 34378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 34478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_start_hc(dev); 34578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 34678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_lock_irqsave(&tmio->lock, flags); 34778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 34878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov misc = tmio_ioread8(tmio->ccr + CCR_MISC); 34978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov misc &= ~(1 << 3); /* USSUSP */ 35078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov tmio_iowrite8(misc, tmio->ccr + CCR_MISC); 35178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 35278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov spin_unlock_irqrestore(&tmio->lock, flags); 35378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 35478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov ohci_finish_controller_resume(hcd); 35578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 35678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov return 0; 35778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov} 35878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#else 35978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define ohci_hcd_tmio_drv_suspend NULL 36078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#define ohci_hcd_tmio_drv_resume NULL 36178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov#endif 36278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov 36378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikovstatic struct platform_driver ohci_hcd_tmio_driver = { 36478c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .probe = ohci_hcd_tmio_drv_probe, 36578c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .remove = __devexit_p(ohci_hcd_tmio_drv_remove), 36678c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .shutdown = usb_hcd_platform_shutdown, 36778c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .suspend = ohci_hcd_tmio_drv_suspend, 36878c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .resume = ohci_hcd_tmio_drv_resume, 36978c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .driver = { 37078c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .name = "tmio-ohci", 37178c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov .owner = THIS_MODULE, 37278c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov }, 37378c73414f4f6744e2ea5a07b263a9698aa6f2416Dmitry Eremin-Solenikov}; 374