root/drivers/usb/host/uhci-grlib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uhci_grlib_init
  2. uhci_hcd_grlib_probe
  3. uhci_hcd_grlib_remove
  4. uhci_hcd_grlib_shutdown

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * UHCI HCD (Host Controller Driver) for GRLIB GRUSBHC
   4  *
   5  * Copyright (c) 2011 Jan Andersson <jan@gaisler.com>
   6  *
   7  * This file is based on UHCI PCI HCD:
   8  * (C) Copyright 1999 Linus Torvalds
   9  * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
  10  * (C) Copyright 1999 Randy Dunlap
  11  * (C) Copyright 1999 Georg Acher, acher@in.tum.de
  12  * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
  13  * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch
  14  * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at
  15  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  16  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  17  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
  18  * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
  19  */
  20 
  21 #include <linux/device.h>
  22 #include <linux/of_irq.h>
  23 #include <linux/of_address.h>
  24 #include <linux/of_platform.h>
  25 
  26 static int uhci_grlib_init(struct usb_hcd *hcd)
  27 {
  28         struct uhci_hcd *uhci = hcd_to_uhci(hcd);
  29 
  30         /*
  31          * Probe to determine the endianness of the controller.
  32          * We know that bit 7 of the PORTSC1 register is always set
  33          * and bit 15 is always clear.  If uhci_readw() yields a value
  34          * with bit 7 (0x80) turned on then the current little-endian
  35          * setting is correct.  Otherwise we assume the value was
  36          * byte-swapped; hence the register interface and presumably
  37          * also the descriptors are big-endian.
  38          */
  39         if (!(uhci_readw(uhci, USBPORTSC1) & 0x80)) {
  40                 uhci->big_endian_mmio = 1;
  41                 uhci->big_endian_desc = 1;
  42         }
  43 
  44         uhci->rh_numports = uhci_count_ports(hcd);
  45 
  46         /* Set up pointers to to generic functions */
  47         uhci->reset_hc = uhci_generic_reset_hc;
  48         uhci->check_and_reset_hc = uhci_generic_check_and_reset_hc;
  49         /* No special actions need to be taken for the functions below */
  50         uhci->configure_hc = NULL;
  51         uhci->resume_detect_interrupts_are_broken = NULL;
  52         uhci->global_suspend_mode_is_broken = NULL;
  53 
  54         /* Reset if the controller isn't already safely quiescent. */
  55         check_and_reset_hc(uhci);
  56         return 0;
  57 }
  58 
  59 static const struct hc_driver uhci_grlib_hc_driver = {
  60         .description =          hcd_name,
  61         .product_desc =         "GRLIB GRUSBHC UHCI Host Controller",
  62         .hcd_priv_size =        sizeof(struct uhci_hcd),
  63 
  64         /* Generic hardware linkage */
  65         .irq =                  uhci_irq,
  66         .flags =                HCD_MEMORY | HCD_DMA | HCD_USB11,
  67 
  68         /* Basic lifecycle operations */
  69         .reset =                uhci_grlib_init,
  70         .start =                uhci_start,
  71 #ifdef CONFIG_PM
  72         .pci_suspend =          NULL,
  73         .pci_resume =           NULL,
  74         .bus_suspend =          uhci_rh_suspend,
  75         .bus_resume =           uhci_rh_resume,
  76 #endif
  77         .stop =                 uhci_stop,
  78 
  79         .urb_enqueue =          uhci_urb_enqueue,
  80         .urb_dequeue =          uhci_urb_dequeue,
  81 
  82         .endpoint_disable =     uhci_hcd_endpoint_disable,
  83         .get_frame_number =     uhci_hcd_get_frame_number,
  84 
  85         .hub_status_data =      uhci_hub_status_data,
  86         .hub_control =          uhci_hub_control,
  87 };
  88 
  89 
  90 static int uhci_hcd_grlib_probe(struct platform_device *op)
  91 {
  92         struct device_node *dn = op->dev.of_node;
  93         struct usb_hcd *hcd;
  94         struct uhci_hcd *uhci = NULL;
  95         struct resource res;
  96         int irq;
  97         int rv;
  98 
  99         if (usb_disabled())
 100                 return -ENODEV;
 101 
 102         dev_dbg(&op->dev, "initializing GRUSBHC UHCI USB Controller\n");
 103 
 104         rv = of_address_to_resource(dn, 0, &res);
 105         if (rv)
 106                 return rv;
 107 
 108         /* usb_create_hcd requires dma_mask != NULL */
 109         op->dev.dma_mask = &op->dev.coherent_dma_mask;
 110         hcd = usb_create_hcd(&uhci_grlib_hc_driver, &op->dev,
 111                         "GRUSBHC UHCI USB");
 112         if (!hcd)
 113                 return -ENOMEM;
 114 
 115         hcd->rsrc_start = res.start;
 116         hcd->rsrc_len = resource_size(&res);
 117 
 118         irq = irq_of_parse_and_map(dn, 0);
 119         if (irq == NO_IRQ) {
 120                 printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
 121                 rv = -EBUSY;
 122                 goto err_usb;
 123         }
 124 
 125         hcd->regs = devm_ioremap_resource(&op->dev, &res);
 126         if (IS_ERR(hcd->regs)) {
 127                 rv = PTR_ERR(hcd->regs);
 128                 goto err_irq;
 129         }
 130 
 131         uhci = hcd_to_uhci(hcd);
 132 
 133         uhci->regs = hcd->regs;
 134 
 135         rv = usb_add_hcd(hcd, irq, 0);
 136         if (rv)
 137                 goto err_irq;
 138 
 139         device_wakeup_enable(hcd->self.controller);
 140         return 0;
 141 
 142 err_irq:
 143         irq_dispose_mapping(irq);
 144 err_usb:
 145         usb_put_hcd(hcd);
 146 
 147         return rv;
 148 }
 149 
 150 static int uhci_hcd_grlib_remove(struct platform_device *op)
 151 {
 152         struct usb_hcd *hcd = platform_get_drvdata(op);
 153 
 154         dev_dbg(&op->dev, "stopping GRLIB GRUSBHC UHCI USB Controller\n");
 155 
 156         usb_remove_hcd(hcd);
 157 
 158         irq_dispose_mapping(hcd->irq);
 159         usb_put_hcd(hcd);
 160 
 161         return 0;
 162 }
 163 
 164 /* Make sure the controller is quiescent and that we're not using it
 165  * any more.  This is mainly for the benefit of programs which, like kexec,
 166  * expect the hardware to be idle: not doing DMA or generating IRQs.
 167  *
 168  * This routine may be called in a damaged or failing kernel.  Hence we
 169  * do not acquire the spinlock before shutting down the controller.
 170  */
 171 static void uhci_hcd_grlib_shutdown(struct platform_device *op)
 172 {
 173         struct usb_hcd *hcd = platform_get_drvdata(op);
 174 
 175         uhci_hc_died(hcd_to_uhci(hcd));
 176 }
 177 
 178 static const struct of_device_id uhci_hcd_grlib_of_match[] = {
 179         { .name = "GAISLER_UHCI", },
 180         { .name = "01_027", },
 181         {},
 182 };
 183 MODULE_DEVICE_TABLE(of, uhci_hcd_grlib_of_match);
 184 
 185 
 186 static struct platform_driver uhci_grlib_driver = {
 187         .probe          = uhci_hcd_grlib_probe,
 188         .remove         = uhci_hcd_grlib_remove,
 189         .shutdown       = uhci_hcd_grlib_shutdown,
 190         .driver = {
 191                 .name = "grlib-uhci",
 192                 .of_match_table = uhci_hcd_grlib_of_match,
 193         },
 194 };

/* [<][>][^][v][top][bottom][index][help] */