1266883Shselasky/* $FreeBSD: stable/11/sys/dev/usb/controller/saf1761_otg_boot.c 308401 2016-11-07 08:36:06Z hselasky $ */ 2266883Shselasky/*- 3266883Shselasky * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org> 4266883Shselasky * All rights reserved. 5266883Shselasky * 6266883Shselasky * This software was developed by SRI International and the University of 7266883Shselasky * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 8266883Shselasky * ("CTSRD"), as part of the DARPA CRASH research programme. 9266883Shselasky * 10266883Shselasky * Redistribution and use in source and binary forms, with or without 11266883Shselasky * modification, are permitted provided that the following conditions 12266883Shselasky * are met: 13266883Shselasky * 1. Redistributions of source code must retain the above copyright 14266883Shselasky * notice, this list of conditions and the following disclaimer. 15266883Shselasky * 2. Redistributions in binary form must reproduce the above copyright 16266883Shselasky * notice, this list of conditions and the following disclaimer in the 17266883Shselasky * documentation and/or other materials provided with the distribution. 18266883Shselasky * 19266883Shselasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20266883Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21266883Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22266883Shselasky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23266883Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24266883Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25266883Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26266883Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27266883Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28266883Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29266883Shselasky * SUCH DAMAGE. 30266883Shselasky */ 31266883Shselasky 32266883Shselasky#include USB_GLOBAL_INCLUDE_FILE 33266883Shselasky 34266883Shselasky#include <dev/usb/controller/saf1761_otg.h> 35266883Shselasky#include <dev/usb/controller/saf1761_otg_reg.h> 36266883Shselasky 37266883Shselaskystatic device_probe_t saf1761_otg_fdt_probe; 38266883Shselaskystatic device_attach_t saf1761_otg_fdt_attach; 39266883Shselaskystatic device_detach_t saf1761_otg_fdt_detach; 40266883Shselasky 41266883Shselaskystatic device_method_t saf1761_otg_methods[] = { 42266883Shselasky /* Device interface */ 43266883Shselasky DEVMETHOD(device_probe, saf1761_otg_fdt_probe), 44266883Shselasky DEVMETHOD(device_attach, saf1761_otg_fdt_attach), 45266883Shselasky DEVMETHOD(device_detach, saf1761_otg_fdt_detach), 46266883Shselasky DEVMETHOD(device_suspend, bus_generic_suspend), 47266883Shselasky DEVMETHOD(device_resume, bus_generic_resume), 48266883Shselasky DEVMETHOD(device_shutdown, bus_generic_shutdown), 49266883Shselasky 50266883Shselasky DEVMETHOD_END 51266883Shselasky}; 52266883Shselasky 53266883Shselaskystatic driver_t saf1761_otg_driver = { 54266883Shselasky .name = "saf1761otg", 55266883Shselasky .methods = saf1761_otg_methods, 56266883Shselasky .size = sizeof(struct saf1761_otg_softc), 57266883Shselasky}; 58266883Shselasky 59266883Shselaskystatic devclass_t saf1761_otg_devclass; 60266883Shselasky 61266883ShselaskyDRIVER_MODULE(saf1761otg, pci, saf1761_otg_driver, saf1761_otg_devclass, 0, 0); 62266883ShselaskyMODULE_DEPEND(saf1761otg, usb, 1, 1, 1); 63266883Shselasky 64266883Shselaskystatic int 65266883Shselaskysaf1761_otg_fdt_probe(device_t dev) 66266883Shselasky{ 67266883Shselasky if (device_get_unit(dev) != 0) 68266883Shselasky return (ENXIO); 69266883Shselasky 70266883Shselasky device_set_desc(dev, "ISP1761/SAF1761 DCI USB 2.0 Device Controller"); 71266883Shselasky 72266883Shselasky return (0); 73266883Shselasky} 74266883Shselasky 75266883Shselaskystatic int 76266883Shselaskysaf1761_otg_fdt_attach(device_t dev) 77266883Shselasky{ 78266883Shselasky struct saf1761_otg_softc *sc = device_get_softc(dev); 79266883Shselasky int err; 80266883Shselasky 81266883Shselasky /* 32-bit data bus */ 82266883Shselasky sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH; 83266883Shselasky 84266883Shselasky /* initialise some bus fields */ 85266883Shselasky sc->sc_bus.parent = dev; 86266883Shselasky sc->sc_bus.devices = sc->sc_devices; 87266883Shselasky sc->sc_bus.devices_max = SOTG_MAX_DEVICES; 88276717Shselasky sc->sc_bus.dma_bits = 32; 89266883Shselasky 90266883Shselasky /* get all DMA memory */ 91266883Shselasky if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev), NULL)) 92266883Shselasky return (ENOMEM); 93266883Shselasky 94266883Shselasky sc->sc_io_res = (void *)1; 95266883Shselasky sc->sc_io_tag = (void *)1; 96266883Shselasky sc->sc_io_hdl = (void *)USB_PCI_MEMORY_ADDRESS; 97266883Shselasky sc->sc_io_size = USB_PCI_MEMORY_SIZE; 98266883Shselasky 99266883Shselasky sc->sc_bus.bdev = device_add_child(dev, "usbus", -1); 100266883Shselasky if (sc->sc_bus.bdev == NULL) 101266883Shselasky goto error; 102266883Shselasky 103266883Shselasky device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); 104266883Shselasky device_set_interrupt(dev, &saf1761_otg_filter_interrupt, &saf1761_otg_interrupt, sc); 105266883Shselasky 106266883Shselasky err = saf1761_otg_init(sc); 107266883Shselasky if (err) { 108266883Shselasky device_printf(dev, "Init failed\n"); 109266883Shselasky goto error; 110266883Shselasky } 111266883Shselasky err = device_probe_and_attach(sc->sc_bus.bdev); 112266883Shselasky if (err) { 113266883Shselasky device_printf(dev, "USB probe and attach failed\n"); 114266883Shselasky goto error; 115266883Shselasky } 116266883Shselasky return (0); 117266883Shselasky 118266883Shselaskyerror: 119266883Shselasky saf1761_otg_fdt_detach(dev); 120266883Shselasky return (ENXIO); 121266883Shselasky} 122266883Shselasky 123266883Shselaskystatic int 124266883Shselaskysaf1761_otg_fdt_detach(device_t dev) 125266883Shselasky{ 126266883Shselasky struct saf1761_otg_softc *sc = device_get_softc(dev); 127266883Shselasky 128266883Shselasky /* during module unload there are lots of children leftover */ 129266883Shselasky device_delete_children(dev); 130266883Shselasky 131266883Shselasky if (sc->sc_irq_res) { 132266883Shselasky /* 133266883Shselasky * Only call uninit() after init() 134266883Shselasky */ 135266883Shselasky saf1761_otg_uninit(sc); 136266883Shselasky } 137266883Shselasky usb_bus_mem_free_all(&sc->sc_bus, NULL); 138266883Shselasky 139266883Shselasky return (0); 140266883Shselasky} 141