saf1761_otg_boot.c revision 308401
155714Skris/* $FreeBSD: stable/11/sys/dev/usb/controller/saf1761_otg_boot.c 308401 2016-11-07 08:36:06Z hselasky $ */ 255714Skris/*- 355714Skris * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org> 455714Skris * All rights reserved. 555714Skris * 655714Skris * This software was developed by SRI International and the University of 755714Skris * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 855714Skris * ("CTSRD"), as part of the DARPA CRASH research programme. 955714Skris * 1055714Skris * Redistribution and use in source and binary forms, with or without 1155714Skris * modification, are permitted provided that the following conditions 1255714Skris * are met: 1355714Skris * 1. Redistributions of source code must retain the above copyright 1455714Skris * notice, this list of conditions and the following disclaimer. 1555714Skris * 2. Redistributions in binary form must reproduce the above copyright 1655714Skris * notice, this list of conditions and the following disclaimer in the 1755714Skris * documentation and/or other materials provided with the distribution. 1855714Skris * 1955714Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2055714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2155714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2255714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2355714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2455714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2555714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2655714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2755714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2855714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2955714Skris * SUCH DAMAGE. 3055714Skris */ 3155714Skris 3255714Skris#include USB_GLOBAL_INCLUDE_FILE 3355714Skris 3455714Skris#include <dev/usb/controller/saf1761_otg.h> 3555714Skris#include <dev/usb/controller/saf1761_otg_reg.h> 3655714Skris 3755714Skrisstatic device_probe_t saf1761_otg_fdt_probe; 3855714Skrisstatic device_attach_t saf1761_otg_fdt_attach; 3955714Skrisstatic device_detach_t saf1761_otg_fdt_detach; 4055714Skris 4155714Skrisstatic device_method_t saf1761_otg_methods[] = { 4255714Skris /* Device interface */ 4355714Skris DEVMETHOD(device_probe, saf1761_otg_fdt_probe), 4455714Skris DEVMETHOD(device_attach, saf1761_otg_fdt_attach), 4555714Skris DEVMETHOD(device_detach, saf1761_otg_fdt_detach), 4655714Skris DEVMETHOD(device_suspend, bus_generic_suspend), 4755714Skris DEVMETHOD(device_resume, bus_generic_resume), 4855714Skris DEVMETHOD(device_shutdown, bus_generic_shutdown), 4955714Skris 5055714Skris DEVMETHOD_END 5155714Skris}; 5255714Skris 5355714Skrisstatic driver_t saf1761_otg_driver = { 5455714Skris .name = "saf1761otg", 5555714Skris .methods = saf1761_otg_methods, 5655714Skris .size = sizeof(struct saf1761_otg_softc), 5755714Skris}; 5855714Skris 5955714Skrisstatic devclass_t saf1761_otg_devclass; 6055714Skris 6155714SkrisDRIVER_MODULE(saf1761otg, pci, saf1761_otg_driver, saf1761_otg_devclass, 0, 0); 62109998SmarkmMODULE_DEPEND(saf1761otg, usb, 1, 1, 1); 63167612Ssimon 64109998Smarkmstatic int 6555714Skrissaf1761_otg_fdt_probe(device_t dev) 6655714Skris{ 6755714Skris if (device_get_unit(dev) != 0) 6855714Skris return (ENXIO); 69109998Smarkm 7055714Skris device_set_desc(dev, "ISP1761/SAF1761 DCI USB 2.0 Device Controller"); 7155714Skris 7255714Skris return (0); 7355714Skris} 7455714Skris 7555714Skrisstatic int 7655714Skrissaf1761_otg_fdt_attach(device_t dev) 7755714Skris{ 7855714Skris struct saf1761_otg_softc *sc = device_get_softc(dev); 7955714Skris int err; 80238405Sjkim 8155714Skris /* 32-bit data bus */ 82111147Snectar sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH; 8355714Skris 8455714Skris /* initialise some bus fields */ 8555714Skris sc->sc_bus.parent = dev; 8655714Skris sc->sc_bus.devices = sc->sc_devices; 8755714Skris sc->sc_bus.devices_max = SOTG_MAX_DEVICES; 8855714Skris sc->sc_bus.dma_bits = 32; 8955714Skris 9055714Skris /* get all DMA memory */ 9155714Skris if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev), NULL)) 9255714Skris return (ENOMEM); 9355714Skris 9455714Skris sc->sc_io_res = (void *)1; 9555714Skris sc->sc_io_tag = (void *)1; 9655714Skris sc->sc_io_hdl = (void *)USB_PCI_MEMORY_ADDRESS; 9755714Skris sc->sc_io_size = USB_PCI_MEMORY_SIZE; 9855714Skris 9955714Skris sc->sc_bus.bdev = device_add_child(dev, "usbus", -1); 10055714Skris if (sc->sc_bus.bdev == NULL) 10155714Skris goto error; 10255714Skris 10355714Skris device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); 10455714Skris device_set_interrupt(dev, &saf1761_otg_filter_interrupt, &saf1761_otg_interrupt, sc); 105160814Ssimon 10655714Skris err = saf1761_otg_init(sc); 10755714Skris if (err) { 108194206Ssimon device_printf(dev, "Init failed\n"); 109194206Ssimon goto error; 110194206Ssimon } 111109998Smarkm err = device_probe_and_attach(sc->sc_bus.bdev); 112160814Ssimon if (err) { 113109998Smarkm device_printf(dev, "USB probe and attach failed\n"); 114160814Ssimon goto error; 11555714Skris } 11655714Skris return (0); 11755714Skris 11855714Skriserror: 11955714Skris saf1761_otg_fdt_detach(dev); 12055714Skris return (ENXIO); 121} 122 123static int 124saf1761_otg_fdt_detach(device_t dev) 125{ 126 struct saf1761_otg_softc *sc = device_get_softc(dev); 127 128 /* during module unload there are lots of children leftover */ 129 device_delete_children(dev); 130 131 if (sc->sc_irq_res) { 132 /* 133 * Only call uninit() after init() 134 */ 135 saf1761_otg_uninit(sc); 136 } 137 usb_bus_mem_free_all(&sc->sc_bus, NULL); 138 139 return (0); 140} 141