cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ohci-sa1111.c (6492B)


      1// SPDX-License-Identifier: GPL-1.0+
      2/*
      3 * OHCI HCD (Host Controller Driver) for USB.
      4 *
      5 * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
      6 * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
      7 * (C) Copyright 2002 Hewlett-Packard Company
      8 *
      9 * SA1111 Bus Glue
     10 *
     11 * Written by Christopher Hoover <ch@hpl.hp.com>
     12 * Based on fragments of previous driver by Russell King et al.
     13 *
     14 * This file is licenced under the GPL.
     15 */
     16
     17#include <asm/mach-types.h>
     18#include <asm/hardware/sa1111.h>
     19
     20#ifndef CONFIG_SA1111
     21#error "This file is SA-1111 bus glue.  CONFIG_SA1111 must be defined."
     22#endif
     23
     24#define USB_STATUS	0x0118
     25#define USB_RESET	0x011c
     26#define USB_IRQTEST	0x0120
     27
     28#define USB_RESET_FORCEIFRESET	(1 << 0)
     29#define USB_RESET_FORCEHCRESET	(1 << 1)
     30#define USB_RESET_CLKGENRESET	(1 << 2)
     31#define USB_RESET_SIMSCALEDOWN	(1 << 3)
     32#define USB_RESET_USBINTTEST	(1 << 4)
     33#define USB_RESET_SLEEPSTBYEN	(1 << 5)
     34#define USB_RESET_PWRSENSELOW	(1 << 6)
     35#define USB_RESET_PWRCTRLLOW	(1 << 7)
     36
     37#define USB_STATUS_IRQHCIRMTWKUP  (1 <<  7)
     38#define USB_STATUS_IRQHCIBUFFACC  (1 <<  8)
     39#define USB_STATUS_NIRQHCIM       (1 <<  9)
     40#define USB_STATUS_NHCIMFCLR      (1 << 10)
     41#define USB_STATUS_USBPWRSENSE    (1 << 11)
     42
     43#if 0
     44static void dump_hci_status(struct usb_hcd *hcd, const char *label)
     45{
     46	unsigned long status = readl_relaxed(hcd->regs + USB_STATUS);
     47
     48	printk(KERN_DEBUG "%s USB_STATUS = { %s%s%s%s%s}\n", label,
     49	     ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
     50	     ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
     51	     ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
     52	     ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "),
     53	     ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : ""));
     54}
     55#endif
     56
     57static int ohci_sa1111_reset(struct usb_hcd *hcd)
     58{
     59	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
     60
     61	ohci_hcd_init(ohci);
     62	return ohci_init(ohci);
     63}
     64
     65static int ohci_sa1111_start(struct usb_hcd *hcd)
     66{
     67	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
     68	int ret;
     69
     70	ret = ohci_run(ohci);
     71	if (ret < 0) {
     72		ohci_err(ohci, "can't start\n");
     73		ohci_stop(hcd);
     74	}
     75	return ret;
     76}
     77
     78static const struct hc_driver ohci_sa1111_hc_driver = {
     79	.description =		hcd_name,
     80	.product_desc =		"SA-1111 OHCI",
     81	.hcd_priv_size =	sizeof(struct ohci_hcd),
     82
     83	/*
     84	 * generic hardware linkage
     85	 */
     86	.irq =			ohci_irq,
     87	.flags =		HCD_USB11 | HCD_DMA | HCD_MEMORY,
     88
     89	/*
     90	 * basic lifecycle operations
     91	 */
     92	.reset =		ohci_sa1111_reset,
     93	.start =		ohci_sa1111_start,
     94	.stop =			ohci_stop,
     95	.shutdown =		ohci_shutdown,
     96
     97	/*
     98	 * managing i/o requests and associated device resources
     99	 */
    100	.urb_enqueue =		ohci_urb_enqueue,
    101	.urb_dequeue =		ohci_urb_dequeue,
    102	.endpoint_disable =	ohci_endpoint_disable,
    103
    104	/*
    105	 * scheduling support
    106	 */
    107	.get_frame_number =	ohci_get_frame,
    108
    109	/*
    110	 * root hub support
    111	 */
    112	.hub_status_data =	ohci_hub_status_data,
    113	.hub_control =		ohci_hub_control,
    114#ifdef	CONFIG_PM
    115	.bus_suspend =		ohci_bus_suspend,
    116	.bus_resume =		ohci_bus_resume,
    117#endif
    118	.start_port_reset =	ohci_start_port_reset,
    119};
    120
    121static int sa1111_start_hc(struct sa1111_dev *dev)
    122{
    123	unsigned int usb_rst = 0;
    124	int ret;
    125
    126	dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n");
    127
    128	if (machine_is_xp860() ||
    129	    machine_is_assabet() ||
    130	    machine_is_pfs168() ||
    131	    machine_is_badge4())
    132		usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW;
    133
    134	/*
    135	 * Configure the power sense and control lines.  Place the USB
    136	 * host controller in reset.
    137	 */
    138	writel_relaxed(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET,
    139		      dev->mapbase + USB_RESET);
    140
    141	/*
    142	 * Now, carefully enable the USB clock, and take
    143	 * the USB host controller out of reset.
    144	 */
    145	ret = sa1111_enable_device(dev);
    146	if (ret == 0) {
    147		udelay(11);
    148		writel_relaxed(usb_rst, dev->mapbase + USB_RESET);
    149	}
    150
    151	return ret;
    152}
    153
    154static void sa1111_stop_hc(struct sa1111_dev *dev)
    155{
    156	unsigned int usb_rst;
    157
    158	dev_dbg(&dev->dev, "stopping SA-1111 OHCI USB Controller\n");
    159
    160	/*
    161	 * Put the USB host controller into reset.
    162	 */
    163	usb_rst = readl_relaxed(dev->mapbase + USB_RESET);
    164	writel_relaxed(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET,
    165		      dev->mapbase + USB_RESET);
    166
    167	/*
    168	 * Stop the USB clock.
    169	 */
    170	sa1111_disable_device(dev);
    171}
    172
    173/**
    174 * ohci_hcd_sa1111_probe - initialize SA-1111-based HCDs
    175 *
    176 * Allocates basic resources for this USB host controller, and
    177 * then invokes the start() method for the HCD associated with it.
    178 */
    179static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev)
    180{
    181	struct usb_hcd *hcd;
    182	int ret, irq;
    183
    184	if (usb_disabled())
    185		return -ENODEV;
    186
    187	/*
    188	 * We don't call dma_set_mask_and_coherent() here because the
    189	 * DMA mask has already been appropraitely setup by the core
    190	 * SA-1111 bus code (which includes bug workarounds.)
    191	 */
    192
    193	hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111");
    194	if (!hcd)
    195		return -ENOMEM;
    196
    197	hcd->rsrc_start = dev->res.start;
    198	hcd->rsrc_len = resource_size(&dev->res);
    199
    200	irq = sa1111_get_irq(dev, 1);
    201	if (irq <= 0) {
    202		ret = irq ? : -ENXIO;
    203		goto err1;
    204	}
    205
    206	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
    207		dev_dbg(&dev->dev, "request_mem_region failed\n");
    208		ret = -EBUSY;
    209		goto err1;
    210	}
    211
    212	hcd->regs = dev->mapbase;
    213
    214	ret = sa1111_start_hc(dev);
    215	if (ret)
    216		goto err2;
    217
    218	ret = usb_add_hcd(hcd, irq, 0);
    219	if (ret == 0) {
    220		device_wakeup_enable(hcd->self.controller);
    221		return ret;
    222	}
    223
    224	sa1111_stop_hc(dev);
    225 err2:
    226	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
    227 err1:
    228	usb_put_hcd(hcd);
    229	return ret;
    230}
    231
    232/**
    233 * ohci_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs
    234 * @dev: USB Host Controller being removed
    235 *
    236 * Reverses the effect of ohci_hcd_sa1111_probe(), first invoking
    237 * the HCD's stop() method.
    238 */
    239static void ohci_hcd_sa1111_remove(struct sa1111_dev *dev)
    240{
    241	struct usb_hcd *hcd = sa1111_get_drvdata(dev);
    242
    243	usb_remove_hcd(hcd);
    244	sa1111_stop_hc(dev);
    245	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
    246	usb_put_hcd(hcd);
    247}
    248
    249static void ohci_hcd_sa1111_shutdown(struct device *_dev)
    250{
    251	struct sa1111_dev *dev = to_sa1111_device(_dev);
    252	struct usb_hcd *hcd = sa1111_get_drvdata(dev);
    253
    254	if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
    255		hcd->driver->shutdown(hcd);
    256		sa1111_stop_hc(dev);
    257	}
    258}
    259
    260static struct sa1111_driver ohci_hcd_sa1111_driver = {
    261	.drv = {
    262		.name	= "sa1111-ohci",
    263		.owner	= THIS_MODULE,
    264		.shutdown = ohci_hcd_sa1111_shutdown,
    265	},
    266	.devid		= SA1111_DEVID_USB,
    267	.probe		= ohci_hcd_sa1111_probe,
    268	.remove		= ohci_hcd_sa1111_remove,
    269};