1c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch/* 2c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Sonics Silicon Backplane 3c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Broadcom USB-core OHCI driver 4c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * 5eb032b9837a958e21ca000358a5bde5e17192ddbMichael Buesch * Copyright 2007 Michael Buesch <m@bues.ch> 6c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * 7c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Derived from the OHCI-PCI driver 8c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Copyright 1999 Roman Weissgaerber 9c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Copyright 2000-2002 David Brownell 10c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Copyright 1999 Linus Torvalds 11c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Copyright 1999 Gregory P. Smith 12c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * 13c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Derived from the USBcore related parts of Broadcom-SB 14c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Copyright 2005 Broadcom Corporation 15c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * 16c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * Licensed under the GNU/GPL. See COPYING for details. 17c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch */ 18c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#include <linux/ssb/ssb.h> 19c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 20c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 21c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29) 22c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 23c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstruct ssb_ohci_device { 24c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ohci_hcd ohci; /* _must_ be at the beginning. */ 25c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 26c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch u32 enable_flags; 27c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch}; 28c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 29c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic inline 30c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstruct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd) 31c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 32c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return (struct ssb_ohci_device *)(hcd->hcd_priv); 33c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 34c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 35c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 36c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic int ssb_ohci_reset(struct usb_hcd *hcd) 37c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 38c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); 39c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ohci_hcd *ohci = &ohcidev->ohci; 40c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch int err; 41c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 42c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ohci_hcd_init(ohci); 43c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch err = ohci_init(ohci); 44c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 45c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return err; 46c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 47c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 48c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic int ssb_ohci_start(struct usb_hcd *hcd) 49c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 50c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); 51c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ohci_hcd *ohci = &ohcidev->ohci; 52c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch int err; 53c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 54c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch err = ohci_run(ohci); 55c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch if (err < 0) { 56c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ohci_err(ohci, "can't start\n"); 57c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ohci_stop(hcd); 58c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch } 59c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 60c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return err; 61c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 62c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 63c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic const struct hc_driver ssb_ohci_hc_driver = { 64c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .description = "ssb-usb-ohci", 65c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .product_desc = "SSB OHCI Controller", 66c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .hcd_priv_size = sizeof(struct ssb_ohci_device), 67c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 68c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .irq = ohci_irq, 69c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .flags = HCD_MEMORY | HCD_USB11, 70c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 71c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .reset = ssb_ohci_reset, 72c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .start = ssb_ohci_start, 73c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .stop = ohci_stop, 74c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .shutdown = ohci_shutdown, 75c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 76c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .urb_enqueue = ohci_urb_enqueue, 77c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .urb_dequeue = ohci_urb_dequeue, 78c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .endpoint_disable = ohci_endpoint_disable, 79c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 80c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .get_frame_number = ohci_get_frame, 81c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 82c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .hub_status_data = ohci_hub_status_data, 83c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .hub_control = ohci_hub_control, 844735b37cf434175c2b7b36b3b68f1e60e8ec8527Al Viro#ifdef CONFIG_PM 85c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .bus_suspend = ohci_bus_suspend, 86c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .bus_resume = ohci_bus_resume, 874735b37cf434175c2b7b36b3b68f1e60e8ec8527Al Viro#endif 88c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 89c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .start_port_reset = ohci_start_port_reset, 90c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch}; 91c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 92c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic void ssb_ohci_detach(struct ssb_device *dev) 93c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 94c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct usb_hcd *hcd = ssb_get_drvdata(dev); 95c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 96f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens if (hcd->driver->shutdown) 97f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens hcd->driver->shutdown(hcd); 98c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch usb_remove_hcd(hcd); 99c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch iounmap(hcd->regs); 100f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 101c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch usb_put_hcd(hcd); 102c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ssb_device_disable(dev, 0); 103c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 104c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 105c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic int ssb_ohci_attach(struct ssb_device *dev) 106c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 107c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ssb_ohci_device *ohcidev; 108c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct usb_hcd *hcd; 109c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch int err = -ENOMEM; 110c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch u32 tmp, flags = 0; 111c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 112f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) || 113f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32))) 114f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens return -EOPNOTSUPP; 115c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 116f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) { 117f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* Put the device into host-mode. */ 118f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens flags |= SSB_OHCI_TMSLOW_HOSTMODE; 119f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_device_enable(dev, flags); 120f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens } else if (dev->id.coreid == SSB_DEV_USB20_HOST) { 121f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* 122f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens * USB 2.0 special considerations: 123f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens * 124f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens * In addition to the standard SSB reset sequence, the Host 125f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens * Control Register must be programmed to bring the USB core 126f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens * and various phy components out of reset. 127f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens */ 128f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_device_enable(dev, 0); 129f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_write32(dev, 0x200, 0x7ff); 130f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens 131f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* Change Flush control reg */ 132f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp = ssb_read32(dev, 0x400); 133f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp &= ~8; 134f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_write32(dev, 0x400, tmp); 135f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp = ssb_read32(dev, 0x400); 136f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens 137f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* Change Shim control reg */ 138f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp = ssb_read32(dev, 0x304); 139f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp &= ~0x100; 140f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_write32(dev, 0x304, tmp); 141f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp = ssb_read32(dev, 0x304); 142f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens 143f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens udelay(1); 144f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens 145f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* Work around for 5354 failures */ 146f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) { 147f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* Change syn01 reg */ 148f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp = 0x00fe00fe; 149f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_write32(dev, 0x894, tmp); 150f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens 151f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens /* Change syn03 reg */ 152f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp = ssb_read32(dev, 0x89c); 153f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens tmp |= 0x1; 154f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_write32(dev, 0x89c, tmp); 155f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens } 156f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens } else 157f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens ssb_device_enable(dev, 0); 158c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 159c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev, 1607071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers dev_name(dev->dev)); 161c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch if (!hcd) 162c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch goto err_dev_disable; 163c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ohcidev = hcd_to_ssb_ohci(hcd); 164c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ohcidev->enable_flags = flags; 165c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 166c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch tmp = ssb_read32(dev, SSB_ADMATCH0); 167c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch hcd->rsrc_start = ssb_admatch_base(tmp); 168c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch hcd->rsrc_len = ssb_admatch_size(tmp); 169c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); 170c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch if (!hcd->regs) 171c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch goto err_put_hcd; 172b5dd18d8747010e3f3eb1cc76a49f94291938559Yong Zhang err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); 173c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch if (err) 174c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch goto err_iounmap; 175c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 176c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ssb_set_drvdata(dev, hcd); 177c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 178c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return err; 179c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 180c604e851486eabcbeb73e984279d436ce121fd5dMichael Buescherr_iounmap: 181c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch iounmap(hcd->regs); 182c604e851486eabcbeb73e984279d436ce121fd5dMichael Buescherr_put_hcd: 183c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch usb_put_hcd(hcd); 184c604e851486eabcbeb73e984279d436ce121fd5dMichael Buescherr_dev_disable: 185c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ssb_device_disable(dev, flags); 186c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return err; 187c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 188c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 189c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic int ssb_ohci_probe(struct ssb_device *dev, 190c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch const struct ssb_device_id *id) 191c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 192c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch int err; 193c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch u16 chipid_top; 194c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 195c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch /* USBcores are only connected on embedded devices. */ 196c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch chipid_top = (dev->bus->chip_id & 0xFF00); 197c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch if (chipid_top != 0x4700 && chipid_top != 0x5300) 198c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return -ENODEV; 199c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 200c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch /* TODO: Probably need checks here; is the core connected? */ 201c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 202c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch if (usb_disabled()) 203c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return -ENODEV; 204c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 205c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch /* We currently always attach SSB_DEV_USB11_HOSTDEV 206c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * as HOST OHCI. If we want to attach it as Client device, 207c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * we must branch here and call into the (yet to 208c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch * be written) Client mode driver. Same for remove(). */ 209c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 210c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch err = ssb_ohci_attach(dev); 211c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 212c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return err; 213c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 214c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 215c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic void ssb_ohci_remove(struct ssb_device *dev) 216c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 217c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ssb_ohci_detach(dev); 218c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 219c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 220c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#ifdef CONFIG_PM 221c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 222c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state) 223c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 224c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ssb_device_disable(dev, 0); 225c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 226c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return 0; 227c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 228c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 229c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic int ssb_ohci_resume(struct ssb_device *dev) 230c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch{ 231c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct usb_hcd *hcd = ssb_get_drvdata(dev); 232c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); 233c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 234c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch ssb_device_enable(dev, ohcidev->enable_flags); 235c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 23643bbb7e015c4380064796c5868b536437b165615Alan Stern ohci_finish_controller_resume(hcd); 237c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch return 0; 238c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch} 239c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 240c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#else /* !CONFIG_PM */ 241c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#define ssb_ohci_suspend NULL 242c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#define ssb_ohci_resume NULL 243c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch#endif /* CONFIG_PM */ 244c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 245c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic const struct ssb_device_id ssb_ohci_table[] = { 246c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV), 247c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV), 248f2402f21caba2aceebbf637458b777300669020fHauke Mehrtens SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV), 249c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch SSB_DEVTABLE_END 250c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch}; 251c604e851486eabcbeb73e984279d436ce121fd5dMichael BueschMODULE_DEVICE_TABLE(ssb, ssb_ohci_table); 252c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch 253c604e851486eabcbeb73e984279d436ce121fd5dMichael Bueschstatic struct ssb_driver ssb_ohci_driver = { 254c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .name = KBUILD_MODNAME, 255c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .id_table = ssb_ohci_table, 256c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .probe = ssb_ohci_probe, 257c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .remove = ssb_ohci_remove, 258c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .suspend = ssb_ohci_suspend, 259c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch .resume = ssb_ohci_resume, 260c604e851486eabcbeb73e984279d436ce121fd5dMichael Buesch}; 261