162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-1.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Open Host Controller Interface (OHCI) driver for USB.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Maintainer: Alan Stern <stern@rowland.harvard.edu>
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
862306a36Sopenharmony_ci * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * [ Initialisation is based on Linus'  ]
1162306a36Sopenharmony_ci * [ uhci code and gregs ohci fragments ]
1262306a36Sopenharmony_ci * [ (C) Copyright 1999 Linus Torvalds  ]
1362306a36Sopenharmony_ci * [ (C) Copyright 1999 Gregory P. Smith]
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller
1762306a36Sopenharmony_ci * interfaces (though some non-x86 Intel chips use it).  It supports
1862306a36Sopenharmony_ci * smarter hardware than UHCI.  A download link for the spec available
1962306a36Sopenharmony_ci * through the https://www.usb.org website.
2062306a36Sopenharmony_ci *
2162306a36Sopenharmony_ci * This file is licenced under the GPL.
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include <linux/module.h>
2562306a36Sopenharmony_ci#include <linux/moduleparam.h>
2662306a36Sopenharmony_ci#include <linux/pci.h>
2762306a36Sopenharmony_ci#include <linux/kernel.h>
2862306a36Sopenharmony_ci#include <linux/delay.h>
2962306a36Sopenharmony_ci#include <linux/ioport.h>
3062306a36Sopenharmony_ci#include <linux/sched.h>
3162306a36Sopenharmony_ci#include <linux/slab.h>
3262306a36Sopenharmony_ci#include <linux/errno.h>
3362306a36Sopenharmony_ci#include <linux/init.h>
3462306a36Sopenharmony_ci#include <linux/timer.h>
3562306a36Sopenharmony_ci#include <linux/list.h>
3662306a36Sopenharmony_ci#include <linux/usb.h>
3762306a36Sopenharmony_ci#include <linux/usb/otg.h>
3862306a36Sopenharmony_ci#include <linux/usb/hcd.h>
3962306a36Sopenharmony_ci#include <linux/dma-mapping.h>
4062306a36Sopenharmony_ci#include <linux/dmapool.h>
4162306a36Sopenharmony_ci#include <linux/workqueue.h>
4262306a36Sopenharmony_ci#include <linux/debugfs.h>
4362306a36Sopenharmony_ci#include <linux/genalloc.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include <asm/io.h>
4662306a36Sopenharmony_ci#include <asm/irq.h>
4762306a36Sopenharmony_ci#include <asm/unaligned.h>
4862306a36Sopenharmony_ci#include <asm/byteorder.h>
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
5262306a36Sopenharmony_ci#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/* For initializing controller (mask in an HCFS mode too) */
5762306a36Sopenharmony_ci#define	OHCI_CONTROL_INIT	OHCI_CTRL_CBSR
5862306a36Sopenharmony_ci#define	OHCI_INTR_INIT \
5962306a36Sopenharmony_ci		(OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE \
6062306a36Sopenharmony_ci		| OHCI_INTR_RD | OHCI_INTR_WDH)
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#ifdef __hppa__
6362306a36Sopenharmony_ci/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
6462306a36Sopenharmony_ci#define	IR_DISABLE
6562306a36Sopenharmony_ci#endif
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci#ifdef CONFIG_ARCH_OMAP
6862306a36Sopenharmony_ci/* OMAP doesn't support IR (no SMM; not needed) */
6962306a36Sopenharmony_ci#define	IR_DISABLE
7062306a36Sopenharmony_ci#endif
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic const char	hcd_name [] = "ohci_hcd";
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define	STATECHANGE_DELAY	msecs_to_jiffies(300)
7762306a36Sopenharmony_ci#define	IO_WATCHDOG_DELAY	msecs_to_jiffies(275)
7862306a36Sopenharmony_ci#define	IO_WATCHDOG_OFF		0xffffff00
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#include "ohci.h"
8162306a36Sopenharmony_ci#include "pci-quirks.h"
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic void ohci_dump(struct ohci_hcd *ohci);
8462306a36Sopenharmony_cistatic void ohci_stop(struct usb_hcd *hcd);
8562306a36Sopenharmony_cistatic void io_watchdog_func(struct timer_list *t);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci#include "ohci-hub.c"
8862306a36Sopenharmony_ci#include "ohci-dbg.c"
8962306a36Sopenharmony_ci#include "ohci-mem.c"
9062306a36Sopenharmony_ci#include "ohci-q.c"
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/*
9462306a36Sopenharmony_ci * On architectures with edge-triggered interrupts we must never return
9562306a36Sopenharmony_ci * IRQ_NONE.
9662306a36Sopenharmony_ci */
9762306a36Sopenharmony_ci#if defined(CONFIG_SA1111)  /* ... or other edge-triggered systems */
9862306a36Sopenharmony_ci#define IRQ_NOTMINE	IRQ_HANDLED
9962306a36Sopenharmony_ci#else
10062306a36Sopenharmony_ci#define IRQ_NOTMINE	IRQ_NONE
10162306a36Sopenharmony_ci#endif
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/* Some boards misreport power switching/overcurrent */
10562306a36Sopenharmony_cistatic bool distrust_firmware;
10662306a36Sopenharmony_cimodule_param (distrust_firmware, bool, 0);
10762306a36Sopenharmony_ciMODULE_PARM_DESC (distrust_firmware,
10862306a36Sopenharmony_ci	"true to distrust firmware power/overcurrent setup");
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/* Some boards leave IR set wrongly, since they fail BIOS/SMM handshakes */
11162306a36Sopenharmony_cistatic bool no_handshake;
11262306a36Sopenharmony_cimodule_param (no_handshake, bool, 0);
11362306a36Sopenharmony_ciMODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake");
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic int number_of_tds(struct urb *urb)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	int			len, i, num, this_sg_len;
12062306a36Sopenharmony_ci	struct scatterlist	*sg;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	len = urb->transfer_buffer_length;
12362306a36Sopenharmony_ci	i = urb->num_mapped_sgs;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	if (len > 0 && i > 0) {		/* Scatter-gather transfer */
12662306a36Sopenharmony_ci		num = 0;
12762306a36Sopenharmony_ci		sg = urb->sg;
12862306a36Sopenharmony_ci		for (;;) {
12962306a36Sopenharmony_ci			this_sg_len = min_t(int, sg_dma_len(sg), len);
13062306a36Sopenharmony_ci			num += DIV_ROUND_UP(this_sg_len, 4096);
13162306a36Sopenharmony_ci			len -= this_sg_len;
13262306a36Sopenharmony_ci			if (--i <= 0 || len <= 0)
13362306a36Sopenharmony_ci				break;
13462306a36Sopenharmony_ci			sg = sg_next(sg);
13562306a36Sopenharmony_ci		}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	} else {			/* Non-SG transfer */
13862306a36Sopenharmony_ci		/* one TD for every 4096 Bytes (could be up to 8K) */
13962306a36Sopenharmony_ci		num = DIV_ROUND_UP(len, 4096);
14062306a36Sopenharmony_ci	}
14162306a36Sopenharmony_ci	return num;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci/*
14562306a36Sopenharmony_ci * queue up an urb for anything except the root hub
14662306a36Sopenharmony_ci */
14762306a36Sopenharmony_cistatic int ohci_urb_enqueue (
14862306a36Sopenharmony_ci	struct usb_hcd	*hcd,
14962306a36Sopenharmony_ci	struct urb	*urb,
15062306a36Sopenharmony_ci	gfp_t		mem_flags
15162306a36Sopenharmony_ci) {
15262306a36Sopenharmony_ci	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
15362306a36Sopenharmony_ci	struct ed	*ed;
15462306a36Sopenharmony_ci	urb_priv_t	*urb_priv;
15562306a36Sopenharmony_ci	unsigned int	pipe = urb->pipe;
15662306a36Sopenharmony_ci	int		i, size = 0;
15762306a36Sopenharmony_ci	unsigned long	flags;
15862306a36Sopenharmony_ci	int		retval = 0;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	/* every endpoint has a ed, locate and maybe (re)initialize it */
16162306a36Sopenharmony_ci	ed = ed_get(ohci, urb->ep, urb->dev, pipe, urb->interval);
16262306a36Sopenharmony_ci	if (! ed)
16362306a36Sopenharmony_ci		return -ENOMEM;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	/* for the private part of the URB we need the number of TDs (size) */
16662306a36Sopenharmony_ci	switch (ed->type) {
16762306a36Sopenharmony_ci		case PIPE_CONTROL:
16862306a36Sopenharmony_ci			/* td_submit_urb() doesn't yet handle these */
16962306a36Sopenharmony_ci			if (urb->transfer_buffer_length > 4096)
17062306a36Sopenharmony_ci				return -EMSGSIZE;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci			/* 1 TD for setup, 1 for ACK, plus ... */
17362306a36Sopenharmony_ci			size = 2;
17462306a36Sopenharmony_ci			fallthrough;
17562306a36Sopenharmony_ci		// case PIPE_INTERRUPT:
17662306a36Sopenharmony_ci		// case PIPE_BULK:
17762306a36Sopenharmony_ci		default:
17862306a36Sopenharmony_ci			size += number_of_tds(urb);
17962306a36Sopenharmony_ci			/* maybe a zero-length packet to wrap it up */
18062306a36Sopenharmony_ci			if (size == 0)
18162306a36Sopenharmony_ci				size++;
18262306a36Sopenharmony_ci			else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0
18362306a36Sopenharmony_ci				&& (urb->transfer_buffer_length
18462306a36Sopenharmony_ci					% usb_maxpacket(urb->dev, pipe)) == 0)
18562306a36Sopenharmony_ci				size++;
18662306a36Sopenharmony_ci			break;
18762306a36Sopenharmony_ci		case PIPE_ISOCHRONOUS: /* number of packets from URB */
18862306a36Sopenharmony_ci			size = urb->number_of_packets;
18962306a36Sopenharmony_ci			break;
19062306a36Sopenharmony_ci	}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	/* allocate the private part of the URB */
19362306a36Sopenharmony_ci	urb_priv = kzalloc(struct_size(urb_priv, td, size), mem_flags);
19462306a36Sopenharmony_ci	if (!urb_priv)
19562306a36Sopenharmony_ci		return -ENOMEM;
19662306a36Sopenharmony_ci	INIT_LIST_HEAD (&urb_priv->pending);
19762306a36Sopenharmony_ci	urb_priv->length = size;
19862306a36Sopenharmony_ci	urb_priv->ed = ed;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	/* allocate the TDs (deferring hash chain updates) */
20162306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
20262306a36Sopenharmony_ci		urb_priv->td [i] = td_alloc (ohci, mem_flags);
20362306a36Sopenharmony_ci		if (!urb_priv->td [i]) {
20462306a36Sopenharmony_ci			urb_priv->length = i;
20562306a36Sopenharmony_ci			urb_free_priv (ohci, urb_priv);
20662306a36Sopenharmony_ci			return -ENOMEM;
20762306a36Sopenharmony_ci		}
20862306a36Sopenharmony_ci	}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	spin_lock_irqsave (&ohci->lock, flags);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* don't submit to a dead HC */
21362306a36Sopenharmony_ci	if (!HCD_HW_ACCESSIBLE(hcd)) {
21462306a36Sopenharmony_ci		retval = -ENODEV;
21562306a36Sopenharmony_ci		goto fail;
21662306a36Sopenharmony_ci	}
21762306a36Sopenharmony_ci	if (ohci->rh_state != OHCI_RH_RUNNING) {
21862306a36Sopenharmony_ci		retval = -ENODEV;
21962306a36Sopenharmony_ci		goto fail;
22062306a36Sopenharmony_ci	}
22162306a36Sopenharmony_ci	retval = usb_hcd_link_urb_to_ep(hcd, urb);
22262306a36Sopenharmony_ci	if (retval)
22362306a36Sopenharmony_ci		goto fail;
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	/* schedule the ed if needed */
22662306a36Sopenharmony_ci	if (ed->state == ED_IDLE) {
22762306a36Sopenharmony_ci		retval = ed_schedule (ohci, ed);
22862306a36Sopenharmony_ci		if (retval < 0) {
22962306a36Sopenharmony_ci			usb_hcd_unlink_urb_from_ep(hcd, urb);
23062306a36Sopenharmony_ci			goto fail;
23162306a36Sopenharmony_ci		}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci		/* Start up the I/O watchdog timer, if it's not running */
23462306a36Sopenharmony_ci		if (ohci->prev_frame_no == IO_WATCHDOG_OFF &&
23562306a36Sopenharmony_ci				list_empty(&ohci->eds_in_use) &&
23662306a36Sopenharmony_ci				!(ohci->flags & OHCI_QUIRK_QEMU)) {
23762306a36Sopenharmony_ci			ohci->prev_frame_no = ohci_frame_no(ohci);
23862306a36Sopenharmony_ci			mod_timer(&ohci->io_watchdog,
23962306a36Sopenharmony_ci					jiffies + IO_WATCHDOG_DELAY);
24062306a36Sopenharmony_ci		}
24162306a36Sopenharmony_ci		list_add(&ed->in_use_list, &ohci->eds_in_use);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci		if (ed->type == PIPE_ISOCHRONOUS) {
24462306a36Sopenharmony_ci			u16	frame = ohci_frame_no(ohci);
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci			/* delay a few frames before the first TD */
24762306a36Sopenharmony_ci			frame += max_t (u16, 8, ed->interval);
24862306a36Sopenharmony_ci			frame &= ~(ed->interval - 1);
24962306a36Sopenharmony_ci			frame |= ed->branch;
25062306a36Sopenharmony_ci			urb->start_frame = frame;
25162306a36Sopenharmony_ci			ed->last_iso = frame + ed->interval * (size - 1);
25262306a36Sopenharmony_ci		}
25362306a36Sopenharmony_ci	} else if (ed->type == PIPE_ISOCHRONOUS) {
25462306a36Sopenharmony_ci		u16	next = ohci_frame_no(ohci) + 1;
25562306a36Sopenharmony_ci		u16	frame = ed->last_iso + ed->interval;
25662306a36Sopenharmony_ci		u16	length = ed->interval * (size - 1);
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci		/* Behind the scheduling threshold? */
25962306a36Sopenharmony_ci		if (unlikely(tick_before(frame, next))) {
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci			/* URB_ISO_ASAP: Round up to the first available slot */
26262306a36Sopenharmony_ci			if (urb->transfer_flags & URB_ISO_ASAP) {
26362306a36Sopenharmony_ci				frame += (next - frame + ed->interval - 1) &
26462306a36Sopenharmony_ci						-ed->interval;
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci			/*
26762306a36Sopenharmony_ci			 * Not ASAP: Use the next slot in the stream,
26862306a36Sopenharmony_ci			 * no matter what.
26962306a36Sopenharmony_ci			 */
27062306a36Sopenharmony_ci			} else {
27162306a36Sopenharmony_ci				/*
27262306a36Sopenharmony_ci				 * Some OHCI hardware doesn't handle late TDs
27362306a36Sopenharmony_ci				 * correctly.  After retiring them it proceeds
27462306a36Sopenharmony_ci				 * to the next ED instead of the next TD.
27562306a36Sopenharmony_ci				 * Therefore we have to omit the late TDs
27662306a36Sopenharmony_ci				 * entirely.
27762306a36Sopenharmony_ci				 */
27862306a36Sopenharmony_ci				urb_priv->td_cnt = DIV_ROUND_UP(
27962306a36Sopenharmony_ci						(u16) (next - frame),
28062306a36Sopenharmony_ci						ed->interval);
28162306a36Sopenharmony_ci				if (urb_priv->td_cnt >= urb_priv->length) {
28262306a36Sopenharmony_ci					++urb_priv->td_cnt;	/* Mark it */
28362306a36Sopenharmony_ci					ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n",
28462306a36Sopenharmony_ci							urb, frame, length,
28562306a36Sopenharmony_ci							next);
28662306a36Sopenharmony_ci				}
28762306a36Sopenharmony_ci			}
28862306a36Sopenharmony_ci		}
28962306a36Sopenharmony_ci		urb->start_frame = frame;
29062306a36Sopenharmony_ci		ed->last_iso = frame + length;
29162306a36Sopenharmony_ci	}
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	/* fill the TDs and link them to the ed; and
29462306a36Sopenharmony_ci	 * enable that part of the schedule, if needed
29562306a36Sopenharmony_ci	 * and update count of queued periodic urbs
29662306a36Sopenharmony_ci	 */
29762306a36Sopenharmony_ci	urb->hcpriv = urb_priv;
29862306a36Sopenharmony_ci	td_submit_urb (ohci, urb);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cifail:
30162306a36Sopenharmony_ci	if (retval)
30262306a36Sopenharmony_ci		urb_free_priv (ohci, urb_priv);
30362306a36Sopenharmony_ci	spin_unlock_irqrestore (&ohci->lock, flags);
30462306a36Sopenharmony_ci	return retval;
30562306a36Sopenharmony_ci}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci/*
30862306a36Sopenharmony_ci * decouple the URB from the HC queues (TDs, urb_priv).
30962306a36Sopenharmony_ci * reporting is always done
31062306a36Sopenharmony_ci * asynchronously, and we might be dealing with an urb that's
31162306a36Sopenharmony_ci * partially transferred, or an ED with other urbs being unlinked.
31262306a36Sopenharmony_ci */
31362306a36Sopenharmony_cistatic int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
31462306a36Sopenharmony_ci{
31562306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
31662306a36Sopenharmony_ci	unsigned long		flags;
31762306a36Sopenharmony_ci	int			rc;
31862306a36Sopenharmony_ci	urb_priv_t		*urb_priv;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	spin_lock_irqsave (&ohci->lock, flags);
32162306a36Sopenharmony_ci	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
32262306a36Sopenharmony_ci	if (rc == 0) {
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci		/* Unless an IRQ completed the unlink while it was being
32562306a36Sopenharmony_ci		 * handed to us, flag it for unlink and giveback, and force
32662306a36Sopenharmony_ci		 * some upcoming INTR_SF to call finish_unlinks()
32762306a36Sopenharmony_ci		 */
32862306a36Sopenharmony_ci		urb_priv = urb->hcpriv;
32962306a36Sopenharmony_ci		if (urb_priv->ed->state == ED_OPER)
33062306a36Sopenharmony_ci			start_ed_unlink(ohci, urb_priv->ed);
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci		if (ohci->rh_state != OHCI_RH_RUNNING) {
33362306a36Sopenharmony_ci			/* With HC dead, we can clean up right away */
33462306a36Sopenharmony_ci			ohci_work(ohci);
33562306a36Sopenharmony_ci		}
33662306a36Sopenharmony_ci	}
33762306a36Sopenharmony_ci	spin_unlock_irqrestore (&ohci->lock, flags);
33862306a36Sopenharmony_ci	return rc;
33962306a36Sopenharmony_ci}
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci/* frees config/altsetting state for endpoints,
34462306a36Sopenharmony_ci * including ED memory, dummy TD, and bulk/intr data toggle
34562306a36Sopenharmony_ci */
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_cistatic void
34862306a36Sopenharmony_ciohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
34962306a36Sopenharmony_ci{
35062306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
35162306a36Sopenharmony_ci	unsigned long		flags;
35262306a36Sopenharmony_ci	struct ed		*ed = ep->hcpriv;
35362306a36Sopenharmony_ci	unsigned		limit = 1000;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	/* ASSERT:  any requests/urbs are being unlinked */
35662306a36Sopenharmony_ci	/* ASSERT:  nobody can be submitting urbs for this any more */
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	if (!ed)
35962306a36Sopenharmony_ci		return;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cirescan:
36262306a36Sopenharmony_ci	spin_lock_irqsave (&ohci->lock, flags);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	if (ohci->rh_state != OHCI_RH_RUNNING) {
36562306a36Sopenharmony_cisanitize:
36662306a36Sopenharmony_ci		ed->state = ED_IDLE;
36762306a36Sopenharmony_ci		ohci_work(ohci);
36862306a36Sopenharmony_ci	}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	switch (ed->state) {
37162306a36Sopenharmony_ci	case ED_UNLINK:		/* wait for hw to finish? */
37262306a36Sopenharmony_ci		/* major IRQ delivery trouble loses INTR_SF too... */
37362306a36Sopenharmony_ci		if (limit-- == 0) {
37462306a36Sopenharmony_ci			ohci_warn(ohci, "ED unlink timeout\n");
37562306a36Sopenharmony_ci			goto sanitize;
37662306a36Sopenharmony_ci		}
37762306a36Sopenharmony_ci		spin_unlock_irqrestore (&ohci->lock, flags);
37862306a36Sopenharmony_ci		schedule_timeout_uninterruptible(1);
37962306a36Sopenharmony_ci		goto rescan;
38062306a36Sopenharmony_ci	case ED_IDLE:		/* fully unlinked */
38162306a36Sopenharmony_ci		if (list_empty (&ed->td_list)) {
38262306a36Sopenharmony_ci			td_free (ohci, ed->dummy);
38362306a36Sopenharmony_ci			ed_free (ohci, ed);
38462306a36Sopenharmony_ci			break;
38562306a36Sopenharmony_ci		}
38662306a36Sopenharmony_ci		fallthrough;
38762306a36Sopenharmony_ci	default:
38862306a36Sopenharmony_ci		/* caller was supposed to have unlinked any requests;
38962306a36Sopenharmony_ci		 * that's not our job.  can't recover; must leak ed.
39062306a36Sopenharmony_ci		 */
39162306a36Sopenharmony_ci		ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n",
39262306a36Sopenharmony_ci			ed, ep->desc.bEndpointAddress, ed->state,
39362306a36Sopenharmony_ci			list_empty (&ed->td_list) ? "" : " (has tds)");
39462306a36Sopenharmony_ci		td_free (ohci, ed->dummy);
39562306a36Sopenharmony_ci		break;
39662306a36Sopenharmony_ci	}
39762306a36Sopenharmony_ci	ep->hcpriv = NULL;
39862306a36Sopenharmony_ci	spin_unlock_irqrestore (&ohci->lock, flags);
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic int ohci_get_frame (struct usb_hcd *hcd)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	return ohci_frame_no(ohci);
40662306a36Sopenharmony_ci}
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistatic void ohci_usb_reset (struct ohci_hcd *ohci)
40962306a36Sopenharmony_ci{
41062306a36Sopenharmony_ci	ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
41162306a36Sopenharmony_ci	ohci->hc_control &= OHCI_CTRL_RWC;
41262306a36Sopenharmony_ci	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
41362306a36Sopenharmony_ci	ohci->rh_state = OHCI_RH_HALTED;
41462306a36Sopenharmony_ci}
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci/* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and
41762306a36Sopenharmony_ci * other cases where the next software may expect clean state from the
41862306a36Sopenharmony_ci * "firmware".  this is bus-neutral, unlike shutdown() methods.
41962306a36Sopenharmony_ci */
42062306a36Sopenharmony_cistatic void _ohci_shutdown(struct usb_hcd *hcd)
42162306a36Sopenharmony_ci{
42262306a36Sopenharmony_ci	struct ohci_hcd *ohci;
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	ohci = hcd_to_ohci (hcd);
42562306a36Sopenharmony_ci	ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable);
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	/* Software reset, after which the controller goes into SUSPEND */
42862306a36Sopenharmony_ci	ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus);
42962306a36Sopenharmony_ci	ohci_readl(ohci, &ohci->regs->cmdstatus);	/* flush the writes */
43062306a36Sopenharmony_ci	udelay(10);
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
43362306a36Sopenharmony_ci	ohci->rh_state = OHCI_RH_HALTED;
43462306a36Sopenharmony_ci}
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic void ohci_shutdown(struct usb_hcd *hcd)
43762306a36Sopenharmony_ci{
43862306a36Sopenharmony_ci	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
43962306a36Sopenharmony_ci	unsigned long flags;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	spin_lock_irqsave(&ohci->lock, flags);
44262306a36Sopenharmony_ci	_ohci_shutdown(hcd);
44362306a36Sopenharmony_ci	spin_unlock_irqrestore(&ohci->lock, flags);
44462306a36Sopenharmony_ci}
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci/*-------------------------------------------------------------------------*
44762306a36Sopenharmony_ci * HC functions
44862306a36Sopenharmony_ci *-------------------------------------------------------------------------*/
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci/* init memory, and kick BIOS/SMM off */
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_cistatic int ohci_init (struct ohci_hcd *ohci)
45362306a36Sopenharmony_ci{
45462306a36Sopenharmony_ci	int ret;
45562306a36Sopenharmony_ci	struct usb_hcd *hcd = ohci_to_hcd(ohci);
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	/* Accept arbitrarily long scatter-gather lists */
45862306a36Sopenharmony_ci	if (!hcd->localmem_pool)
45962306a36Sopenharmony_ci		hcd->self.sg_tablesize = ~0;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	if (distrust_firmware)
46262306a36Sopenharmony_ci		ohci->flags |= OHCI_QUIRK_HUB_POWER;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	ohci->rh_state = OHCI_RH_HALTED;
46562306a36Sopenharmony_ci	ohci->regs = hcd->regs;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	/* REVISIT this BIOS handshake is now moved into PCI "quirks", and
46862306a36Sopenharmony_ci	 * was never needed for most non-PCI systems ... remove the code?
46962306a36Sopenharmony_ci	 */
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci#ifndef IR_DISABLE
47262306a36Sopenharmony_ci	/* SMM owns the HC?  not for long! */
47362306a36Sopenharmony_ci	if (!no_handshake && ohci_readl (ohci,
47462306a36Sopenharmony_ci					&ohci->regs->control) & OHCI_CTRL_IR) {
47562306a36Sopenharmony_ci		u32 temp;
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci		ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci		/* this timeout is arbitrary.  we make it long, so systems
48062306a36Sopenharmony_ci		 * depending on usb keyboards may be usable even if the
48162306a36Sopenharmony_ci		 * BIOS/SMM code seems pretty broken.
48262306a36Sopenharmony_ci		 */
48362306a36Sopenharmony_ci		temp = 500;	/* arbitrary: five seconds */
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci		ohci_writel (ohci, OHCI_INTR_OC, &ohci->regs->intrenable);
48662306a36Sopenharmony_ci		ohci_writel (ohci, OHCI_OCR, &ohci->regs->cmdstatus);
48762306a36Sopenharmony_ci		while (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_IR) {
48862306a36Sopenharmony_ci			msleep (10);
48962306a36Sopenharmony_ci			if (--temp == 0) {
49062306a36Sopenharmony_ci				ohci_err (ohci, "USB HC takeover failed!"
49162306a36Sopenharmony_ci					"  (BIOS/SMM bug)\n");
49262306a36Sopenharmony_ci				return -EBUSY;
49362306a36Sopenharmony_ci			}
49462306a36Sopenharmony_ci		}
49562306a36Sopenharmony_ci		ohci_usb_reset (ohci);
49662306a36Sopenharmony_ci	}
49762306a36Sopenharmony_ci#endif
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	/* Disable HC interrupts */
50062306a36Sopenharmony_ci	ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	/* flush the writes, and save key bits like RWC */
50362306a36Sopenharmony_ci	if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC)
50462306a36Sopenharmony_ci		ohci->hc_control |= OHCI_CTRL_RWC;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	/* Read the number of ports unless overridden */
50762306a36Sopenharmony_ci	if (ohci->num_ports == 0)
50862306a36Sopenharmony_ci		ohci->num_ports = roothub_a(ohci) & RH_A_NDP;
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	if (ohci->hcca)
51162306a36Sopenharmony_ci		return 0;
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	timer_setup(&ohci->io_watchdog, io_watchdog_func, 0);
51462306a36Sopenharmony_ci	ohci->prev_frame_no = IO_WATCHDOG_OFF;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	if (hcd->localmem_pool)
51762306a36Sopenharmony_ci		ohci->hcca = gen_pool_dma_alloc_align(hcd->localmem_pool,
51862306a36Sopenharmony_ci						sizeof(*ohci->hcca),
51962306a36Sopenharmony_ci						&ohci->hcca_dma, 256);
52062306a36Sopenharmony_ci	else
52162306a36Sopenharmony_ci		ohci->hcca = dma_alloc_coherent(hcd->self.controller,
52262306a36Sopenharmony_ci						sizeof(*ohci->hcca),
52362306a36Sopenharmony_ci						&ohci->hcca_dma,
52462306a36Sopenharmony_ci						GFP_KERNEL);
52562306a36Sopenharmony_ci	if (!ohci->hcca)
52662306a36Sopenharmony_ci		return -ENOMEM;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	if ((ret = ohci_mem_init (ohci)) < 0)
52962306a36Sopenharmony_ci		ohci_stop (hcd);
53062306a36Sopenharmony_ci	else {
53162306a36Sopenharmony_ci		create_debug_files (ohci);
53262306a36Sopenharmony_ci	}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	return ret;
53562306a36Sopenharmony_ci}
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci/* Start an OHCI controller, set the BUS operational
54062306a36Sopenharmony_ci * resets USB and controller
54162306a36Sopenharmony_ci * enable interrupts
54262306a36Sopenharmony_ci */
54362306a36Sopenharmony_cistatic int ohci_run (struct ohci_hcd *ohci)
54462306a36Sopenharmony_ci{
54562306a36Sopenharmony_ci	u32			mask, val;
54662306a36Sopenharmony_ci	int			first = ohci->fminterval == 0;
54762306a36Sopenharmony_ci	struct usb_hcd		*hcd = ohci_to_hcd(ohci);
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	ohci->rh_state = OHCI_RH_HALTED;
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	/* boot firmware should have set this up (5.1.1.3.1) */
55262306a36Sopenharmony_ci	if (first) {
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci		val = ohci_readl (ohci, &ohci->regs->fminterval);
55562306a36Sopenharmony_ci		ohci->fminterval = val & 0x3fff;
55662306a36Sopenharmony_ci		if (ohci->fminterval != FI)
55762306a36Sopenharmony_ci			ohci_dbg (ohci, "fminterval delta %d\n",
55862306a36Sopenharmony_ci				ohci->fminterval - FI);
55962306a36Sopenharmony_ci		ohci->fminterval |= FSMP (ohci->fminterval) << 16;
56062306a36Sopenharmony_ci		/* also: power/overcurrent flags in roothub.a */
56162306a36Sopenharmony_ci	}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci	/* Reset USB nearly "by the book".  RemoteWakeupConnected has
56462306a36Sopenharmony_ci	 * to be checked in case boot firmware (BIOS/SMM/...) has set up
56562306a36Sopenharmony_ci	 * wakeup in a way the bus isn't aware of (e.g., legacy PCI PM).
56662306a36Sopenharmony_ci	 * If the bus glue detected wakeup capability then it should
56762306a36Sopenharmony_ci	 * already be enabled; if so we'll just enable it again.
56862306a36Sopenharmony_ci	 */
56962306a36Sopenharmony_ci	if ((ohci->hc_control & OHCI_CTRL_RWC) != 0)
57062306a36Sopenharmony_ci		device_set_wakeup_capable(hcd->self.controller, 1);
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
57362306a36Sopenharmony_ci	case OHCI_USB_OPER:
57462306a36Sopenharmony_ci		val = 0;
57562306a36Sopenharmony_ci		break;
57662306a36Sopenharmony_ci	case OHCI_USB_SUSPEND:
57762306a36Sopenharmony_ci	case OHCI_USB_RESUME:
57862306a36Sopenharmony_ci		ohci->hc_control &= OHCI_CTRL_RWC;
57962306a36Sopenharmony_ci		ohci->hc_control |= OHCI_USB_RESUME;
58062306a36Sopenharmony_ci		val = 10 /* msec wait */;
58162306a36Sopenharmony_ci		break;
58262306a36Sopenharmony_ci	// case OHCI_USB_RESET:
58362306a36Sopenharmony_ci	default:
58462306a36Sopenharmony_ci		ohci->hc_control &= OHCI_CTRL_RWC;
58562306a36Sopenharmony_ci		ohci->hc_control |= OHCI_USB_RESET;
58662306a36Sopenharmony_ci		val = 50 /* msec wait */;
58762306a36Sopenharmony_ci		break;
58862306a36Sopenharmony_ci	}
58962306a36Sopenharmony_ci	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
59062306a36Sopenharmony_ci	// flush the writes
59162306a36Sopenharmony_ci	(void) ohci_readl (ohci, &ohci->regs->control);
59262306a36Sopenharmony_ci	msleep(val);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	/* 2msec timelimit here means no irqs/preempt */
59762306a36Sopenharmony_ci	spin_lock_irq (&ohci->lock);
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ciretry:
60062306a36Sopenharmony_ci	/* HC Reset requires max 10 us delay */
60162306a36Sopenharmony_ci	ohci_writel (ohci, OHCI_HCR,  &ohci->regs->cmdstatus);
60262306a36Sopenharmony_ci	val = 30;	/* ... allow extra time */
60362306a36Sopenharmony_ci	while ((ohci_readl (ohci, &ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
60462306a36Sopenharmony_ci		if (--val == 0) {
60562306a36Sopenharmony_ci			spin_unlock_irq (&ohci->lock);
60662306a36Sopenharmony_ci			ohci_err (ohci, "USB HC reset timed out!\n");
60762306a36Sopenharmony_ci			return -1;
60862306a36Sopenharmony_ci		}
60962306a36Sopenharmony_ci		udelay (1);
61062306a36Sopenharmony_ci	}
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	/* now we're in the SUSPEND state ... must go OPERATIONAL
61362306a36Sopenharmony_ci	 * within 2msec else HC enters RESUME
61462306a36Sopenharmony_ci	 *
61562306a36Sopenharmony_ci	 * ... but some hardware won't init fmInterval "by the book"
61662306a36Sopenharmony_ci	 * (SiS, OPTi ...), so reset again instead.  SiS doesn't need
61762306a36Sopenharmony_ci	 * this if we write fmInterval after we're OPERATIONAL.
61862306a36Sopenharmony_ci	 * Unclear about ALi, ServerWorks, and others ... this could
61962306a36Sopenharmony_ci	 * easily be a longstanding bug in chip init on Linux.
62062306a36Sopenharmony_ci	 */
62162306a36Sopenharmony_ci	if (ohci->flags & OHCI_QUIRK_INITRESET) {
62262306a36Sopenharmony_ci		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
62362306a36Sopenharmony_ci		// flush those writes
62462306a36Sopenharmony_ci		(void) ohci_readl (ohci, &ohci->regs->control);
62562306a36Sopenharmony_ci	}
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	/* Tell the controller where the control and bulk lists are
62862306a36Sopenharmony_ci	 * The lists are empty now. */
62962306a36Sopenharmony_ci	ohci_writel (ohci, 0, &ohci->regs->ed_controlhead);
63062306a36Sopenharmony_ci	ohci_writel (ohci, 0, &ohci->regs->ed_bulkhead);
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	/* a reset clears this */
63362306a36Sopenharmony_ci	ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca);
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	periodic_reinit (ohci);
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	/* some OHCI implementations are finicky about how they init.
63862306a36Sopenharmony_ci	 * bogus values here mean not even enumeration could work.
63962306a36Sopenharmony_ci	 */
64062306a36Sopenharmony_ci	if ((ohci_readl (ohci, &ohci->regs->fminterval) & 0x3fff0000) == 0
64162306a36Sopenharmony_ci			|| !ohci_readl (ohci, &ohci->regs->periodicstart)) {
64262306a36Sopenharmony_ci		if (!(ohci->flags & OHCI_QUIRK_INITRESET)) {
64362306a36Sopenharmony_ci			ohci->flags |= OHCI_QUIRK_INITRESET;
64462306a36Sopenharmony_ci			ohci_dbg (ohci, "enabling initreset quirk\n");
64562306a36Sopenharmony_ci			goto retry;
64662306a36Sopenharmony_ci		}
64762306a36Sopenharmony_ci		spin_unlock_irq (&ohci->lock);
64862306a36Sopenharmony_ci		ohci_err (ohci, "init err (%08x %04x)\n",
64962306a36Sopenharmony_ci			ohci_readl (ohci, &ohci->regs->fminterval),
65062306a36Sopenharmony_ci			ohci_readl (ohci, &ohci->regs->periodicstart));
65162306a36Sopenharmony_ci		return -EOVERFLOW;
65262306a36Sopenharmony_ci	}
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	/* use rhsc irqs after hub_wq is allocated */
65562306a36Sopenharmony_ci	set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
65662306a36Sopenharmony_ci	hcd->uses_new_polling = 1;
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	/* start controller operations */
65962306a36Sopenharmony_ci	ohci->hc_control &= OHCI_CTRL_RWC;
66062306a36Sopenharmony_ci	ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
66162306a36Sopenharmony_ci	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
66262306a36Sopenharmony_ci	ohci->rh_state = OHCI_RH_RUNNING;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	/* wake on ConnectStatusChange, matching external hubs */
66562306a36Sopenharmony_ci	ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	/* Choose the interrupts we care about now, others later on demand */
66862306a36Sopenharmony_ci	mask = OHCI_INTR_INIT;
66962306a36Sopenharmony_ci	ohci_writel (ohci, ~0, &ohci->regs->intrstatus);
67062306a36Sopenharmony_ci	ohci_writel (ohci, mask, &ohci->regs->intrenable);
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	/* handle root hub init quirks ... */
67362306a36Sopenharmony_ci	val = roothub_a (ohci);
67462306a36Sopenharmony_ci	/* Configure for per-port over-current protection by default */
67562306a36Sopenharmony_ci	val &= ~RH_A_NOCP;
67662306a36Sopenharmony_ci	val |= RH_A_OCPM;
67762306a36Sopenharmony_ci	if (ohci->flags & OHCI_QUIRK_SUPERIO) {
67862306a36Sopenharmony_ci		/* NSC 87560 and maybe others.
67962306a36Sopenharmony_ci		 * Ganged power switching, no over-current protection.
68062306a36Sopenharmony_ci		 */
68162306a36Sopenharmony_ci		val |= RH_A_NOCP;
68262306a36Sopenharmony_ci		val &= ~(RH_A_POTPGT | RH_A_NPS | RH_A_PSM | RH_A_OCPM);
68362306a36Sopenharmony_ci	} else if ((ohci->flags & OHCI_QUIRK_AMD756) ||
68462306a36Sopenharmony_ci			(ohci->flags & OHCI_QUIRK_HUB_POWER)) {
68562306a36Sopenharmony_ci		/* hub power always on; required for AMD-756 and some
68662306a36Sopenharmony_ci		 * Mac platforms.
68762306a36Sopenharmony_ci		 */
68862306a36Sopenharmony_ci		val |= RH_A_NPS;
68962306a36Sopenharmony_ci	}
69062306a36Sopenharmony_ci	ohci_writel(ohci, val, &ohci->regs->roothub.a);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	ohci_writel (ohci, RH_HS_LPSC, &ohci->regs->roothub.status);
69362306a36Sopenharmony_ci	ohci_writel (ohci, (val & RH_A_NPS) ? 0 : RH_B_PPCM,
69462306a36Sopenharmony_ci						&ohci->regs->roothub.b);
69562306a36Sopenharmony_ci	// flush those writes
69662306a36Sopenharmony_ci	(void) ohci_readl (ohci, &ohci->regs->control);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci	ohci->next_statechange = jiffies + STATECHANGE_DELAY;
69962306a36Sopenharmony_ci	spin_unlock_irq (&ohci->lock);
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	// POTPGT delay is bits 24-31, in 2 ms units.
70262306a36Sopenharmony_ci	mdelay ((val >> 23) & 0x1fe);
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci	ohci_dump(ohci);
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci	return 0;
70762306a36Sopenharmony_ci}
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci/* ohci_setup routine for generic controller initialization */
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ciint ohci_setup(struct usb_hcd *hcd)
71262306a36Sopenharmony_ci{
71362306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	ohci_hcd_init(ohci);
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	return ohci_init(ohci);
71862306a36Sopenharmony_ci}
71962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ohci_setup);
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci/* ohci_start routine for generic controller start of all OHCI bus glue */
72262306a36Sopenharmony_cistatic int ohci_start(struct usb_hcd *hcd)
72362306a36Sopenharmony_ci{
72462306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
72562306a36Sopenharmony_ci	int	ret;
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci	ret = ohci_run(ohci);
72862306a36Sopenharmony_ci	if (ret < 0) {
72962306a36Sopenharmony_ci		ohci_err(ohci, "can't start\n");
73062306a36Sopenharmony_ci		ohci_stop(hcd);
73162306a36Sopenharmony_ci	}
73262306a36Sopenharmony_ci	return ret;
73362306a36Sopenharmony_ci}
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci/*
73862306a36Sopenharmony_ci * Some OHCI controllers are known to lose track of completed TDs.  They
73962306a36Sopenharmony_ci * don't add the TDs to the hardware done queue, which means we never see
74062306a36Sopenharmony_ci * them as being completed.
74162306a36Sopenharmony_ci *
74262306a36Sopenharmony_ci * This watchdog routine checks for such problems.  Without some way to
74362306a36Sopenharmony_ci * tell when those TDs have completed, we would never take their EDs off
74462306a36Sopenharmony_ci * the unlink list.  As a result, URBs could never be dequeued and
74562306a36Sopenharmony_ci * endpoints could never be released.
74662306a36Sopenharmony_ci */
74762306a36Sopenharmony_cistatic void io_watchdog_func(struct timer_list *t)
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	struct ohci_hcd	*ohci = from_timer(ohci, t, io_watchdog);
75062306a36Sopenharmony_ci	bool		takeback_all_pending = false;
75162306a36Sopenharmony_ci	u32		status;
75262306a36Sopenharmony_ci	u32		head;
75362306a36Sopenharmony_ci	struct ed	*ed;
75462306a36Sopenharmony_ci	struct td	*td, *td_start, *td_next;
75562306a36Sopenharmony_ci	unsigned	frame_no, prev_frame_no = IO_WATCHDOG_OFF;
75662306a36Sopenharmony_ci	unsigned long	flags;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	spin_lock_irqsave(&ohci->lock, flags);
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ci	/*
76162306a36Sopenharmony_ci	 * One way to lose track of completed TDs is if the controller
76262306a36Sopenharmony_ci	 * never writes back the done queue head.  If it hasn't been
76362306a36Sopenharmony_ci	 * written back since the last time this function ran and if it
76462306a36Sopenharmony_ci	 * was non-empty at that time, something is badly wrong with the
76562306a36Sopenharmony_ci	 * hardware.
76662306a36Sopenharmony_ci	 */
76762306a36Sopenharmony_ci	status = ohci_readl(ohci, &ohci->regs->intrstatus);
76862306a36Sopenharmony_ci	if (!(status & OHCI_INTR_WDH) && ohci->wdh_cnt == ohci->prev_wdh_cnt) {
76962306a36Sopenharmony_ci		if (ohci->prev_donehead) {
77062306a36Sopenharmony_ci			ohci_err(ohci, "HcDoneHead not written back; disabled\n");
77162306a36Sopenharmony_ci died:
77262306a36Sopenharmony_ci			usb_hc_died(ohci_to_hcd(ohci));
77362306a36Sopenharmony_ci			ohci_dump(ohci);
77462306a36Sopenharmony_ci			_ohci_shutdown(ohci_to_hcd(ohci));
77562306a36Sopenharmony_ci			goto done;
77662306a36Sopenharmony_ci		} else {
77762306a36Sopenharmony_ci			/* No write back because the done queue was empty */
77862306a36Sopenharmony_ci			takeback_all_pending = true;
77962306a36Sopenharmony_ci		}
78062306a36Sopenharmony_ci	}
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	/* Check every ED which might have pending TDs */
78362306a36Sopenharmony_ci	list_for_each_entry(ed, &ohci->eds_in_use, in_use_list) {
78462306a36Sopenharmony_ci		if (ed->pending_td) {
78562306a36Sopenharmony_ci			if (takeback_all_pending ||
78662306a36Sopenharmony_ci					OKAY_TO_TAKEBACK(ohci, ed)) {
78762306a36Sopenharmony_ci				unsigned tmp = hc32_to_cpu(ohci, ed->hwINFO);
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci				ohci_dbg(ohci, "takeback pending TD for dev %d ep 0x%x\n",
79062306a36Sopenharmony_ci						0x007f & tmp,
79162306a36Sopenharmony_ci						(0x000f & (tmp >> 7)) +
79262306a36Sopenharmony_ci							((tmp & ED_IN) >> 5));
79362306a36Sopenharmony_ci				add_to_done_list(ohci, ed->pending_td);
79462306a36Sopenharmony_ci			}
79562306a36Sopenharmony_ci		}
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci		/* Starting from the latest pending TD, */
79862306a36Sopenharmony_ci		td = ed->pending_td;
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci		/* or the last TD on the done list, */
80162306a36Sopenharmony_ci		if (!td) {
80262306a36Sopenharmony_ci			list_for_each_entry(td_next, &ed->td_list, td_list) {
80362306a36Sopenharmony_ci				if (!td_next->next_dl_td)
80462306a36Sopenharmony_ci					break;
80562306a36Sopenharmony_ci				td = td_next;
80662306a36Sopenharmony_ci			}
80762306a36Sopenharmony_ci		}
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci		/* find the last TD processed by the controller. */
81062306a36Sopenharmony_ci		head = hc32_to_cpu(ohci, READ_ONCE(ed->hwHeadP)) & TD_MASK;
81162306a36Sopenharmony_ci		td_start = td;
81262306a36Sopenharmony_ci		td_next = list_prepare_entry(td, &ed->td_list, td_list);
81362306a36Sopenharmony_ci		list_for_each_entry_continue(td_next, &ed->td_list, td_list) {
81462306a36Sopenharmony_ci			if (head == (u32) td_next->td_dma)
81562306a36Sopenharmony_ci				break;
81662306a36Sopenharmony_ci			td = td_next;	/* head pointer has passed this TD */
81762306a36Sopenharmony_ci		}
81862306a36Sopenharmony_ci		if (td != td_start) {
81962306a36Sopenharmony_ci			/*
82062306a36Sopenharmony_ci			 * In case a WDH cycle is in progress, we will wait
82162306a36Sopenharmony_ci			 * for the next two cycles to complete before assuming
82262306a36Sopenharmony_ci			 * this TD will never get on the done queue.
82362306a36Sopenharmony_ci			 */
82462306a36Sopenharmony_ci			ed->takeback_wdh_cnt = ohci->wdh_cnt + 2;
82562306a36Sopenharmony_ci			ed->pending_td = td;
82662306a36Sopenharmony_ci		}
82762306a36Sopenharmony_ci	}
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci	ohci_work(ohci);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	if (ohci->rh_state == OHCI_RH_RUNNING) {
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci		/*
83462306a36Sopenharmony_ci		 * Sometimes a controller just stops working.  We can tell
83562306a36Sopenharmony_ci		 * by checking that the frame counter has advanced since
83662306a36Sopenharmony_ci		 * the last time we ran.
83762306a36Sopenharmony_ci		 *
83862306a36Sopenharmony_ci		 * But be careful: Some controllers violate the spec by
83962306a36Sopenharmony_ci		 * stopping their frame counter when no ports are active.
84062306a36Sopenharmony_ci		 */
84162306a36Sopenharmony_ci		frame_no = ohci_frame_no(ohci);
84262306a36Sopenharmony_ci		if (frame_no == ohci->prev_frame_no) {
84362306a36Sopenharmony_ci			int		active_cnt = 0;
84462306a36Sopenharmony_ci			int		i;
84562306a36Sopenharmony_ci			unsigned	tmp;
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci			for (i = 0; i < ohci->num_ports; ++i) {
84862306a36Sopenharmony_ci				tmp = roothub_portstatus(ohci, i);
84962306a36Sopenharmony_ci				/* Enabled and not suspended? */
85062306a36Sopenharmony_ci				if ((tmp & RH_PS_PES) && !(tmp & RH_PS_PSS))
85162306a36Sopenharmony_ci					++active_cnt;
85262306a36Sopenharmony_ci			}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci			if (active_cnt > 0) {
85562306a36Sopenharmony_ci				ohci_err(ohci, "frame counter not updating; disabled\n");
85662306a36Sopenharmony_ci				goto died;
85762306a36Sopenharmony_ci			}
85862306a36Sopenharmony_ci		}
85962306a36Sopenharmony_ci		if (!list_empty(&ohci->eds_in_use)) {
86062306a36Sopenharmony_ci			prev_frame_no = frame_no;
86162306a36Sopenharmony_ci			ohci->prev_wdh_cnt = ohci->wdh_cnt;
86262306a36Sopenharmony_ci			ohci->prev_donehead = ohci_readl(ohci,
86362306a36Sopenharmony_ci					&ohci->regs->donehead);
86462306a36Sopenharmony_ci			mod_timer(&ohci->io_watchdog,
86562306a36Sopenharmony_ci					jiffies + IO_WATCHDOG_DELAY);
86662306a36Sopenharmony_ci		}
86762306a36Sopenharmony_ci	}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci done:
87062306a36Sopenharmony_ci	ohci->prev_frame_no = prev_frame_no;
87162306a36Sopenharmony_ci	spin_unlock_irqrestore(&ohci->lock, flags);
87262306a36Sopenharmony_ci}
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci/* an interrupt happens */
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_cistatic irqreturn_t ohci_irq (struct usb_hcd *hcd)
87762306a36Sopenharmony_ci{
87862306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
87962306a36Sopenharmony_ci	struct ohci_regs __iomem *regs = ohci->regs;
88062306a36Sopenharmony_ci	int			ints;
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci	/* Read interrupt status (and flush pending writes).  We ignore the
88362306a36Sopenharmony_ci	 * optimization of checking the LSB of hcca->done_head; it doesn't
88462306a36Sopenharmony_ci	 * work on all systems (edge triggering for OHCI can be a factor).
88562306a36Sopenharmony_ci	 */
88662306a36Sopenharmony_ci	ints = ohci_readl(ohci, &regs->intrstatus);
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	/* Check for an all 1's result which is a typical consequence
88962306a36Sopenharmony_ci	 * of dead, unclocked, or unplugged (CardBus...) devices
89062306a36Sopenharmony_ci	 */
89162306a36Sopenharmony_ci	if (ints == ~(u32)0) {
89262306a36Sopenharmony_ci		ohci->rh_state = OHCI_RH_HALTED;
89362306a36Sopenharmony_ci		ohci_dbg (ohci, "device removed!\n");
89462306a36Sopenharmony_ci		usb_hc_died(hcd);
89562306a36Sopenharmony_ci		return IRQ_HANDLED;
89662306a36Sopenharmony_ci	}
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	/* We only care about interrupts that are enabled */
89962306a36Sopenharmony_ci	ints &= ohci_readl(ohci, &regs->intrenable);
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	/* interrupt for some other device? */
90262306a36Sopenharmony_ci	if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED))
90362306a36Sopenharmony_ci		return IRQ_NOTMINE;
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci	if (ints & OHCI_INTR_UE) {
90662306a36Sopenharmony_ci		// e.g. due to PCI Master/Target Abort
90762306a36Sopenharmony_ci		if (quirk_nec(ohci)) {
90862306a36Sopenharmony_ci			/* Workaround for a silicon bug in some NEC chips used
90962306a36Sopenharmony_ci			 * in Apple's PowerBooks. Adapted from Darwin code.
91062306a36Sopenharmony_ci			 */
91162306a36Sopenharmony_ci			ohci_err (ohci, "OHCI Unrecoverable Error, scheduling NEC chip restart\n");
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci			ohci_writel (ohci, OHCI_INTR_UE, &regs->intrdisable);
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci			schedule_work (&ohci->nec_work);
91662306a36Sopenharmony_ci		} else {
91762306a36Sopenharmony_ci			ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
91862306a36Sopenharmony_ci			ohci->rh_state = OHCI_RH_HALTED;
91962306a36Sopenharmony_ci			usb_hc_died(hcd);
92062306a36Sopenharmony_ci		}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci		ohci_dump(ohci);
92362306a36Sopenharmony_ci		ohci_usb_reset (ohci);
92462306a36Sopenharmony_ci	}
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci	if (ints & OHCI_INTR_RHSC) {
92762306a36Sopenharmony_ci		ohci_dbg(ohci, "rhsc\n");
92862306a36Sopenharmony_ci		ohci->next_statechange = jiffies + STATECHANGE_DELAY;
92962306a36Sopenharmony_ci		ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,
93062306a36Sopenharmony_ci				&regs->intrstatus);
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_ci		/* NOTE: Vendors didn't always make the same implementation
93362306a36Sopenharmony_ci		 * choices for RHSC.  Many followed the spec; RHSC triggers
93462306a36Sopenharmony_ci		 * on an edge, like setting and maybe clearing a port status
93562306a36Sopenharmony_ci		 * change bit.  With others it's level-triggered, active
93662306a36Sopenharmony_ci		 * until hub_wq clears all the port status change bits.  We'll
93762306a36Sopenharmony_ci		 * always disable it here and rely on polling until hub_wq
93862306a36Sopenharmony_ci		 * re-enables it.
93962306a36Sopenharmony_ci		 */
94062306a36Sopenharmony_ci		ohci_writel(ohci, OHCI_INTR_RHSC, &regs->intrdisable);
94162306a36Sopenharmony_ci		usb_hcd_poll_rh_status(hcd);
94262306a36Sopenharmony_ci	}
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	/* For connect and disconnect events, we expect the controller
94562306a36Sopenharmony_ci	 * to turn on RHSC along with RD.  But for remote wakeup events
94662306a36Sopenharmony_ci	 * this might not happen.
94762306a36Sopenharmony_ci	 */
94862306a36Sopenharmony_ci	else if (ints & OHCI_INTR_RD) {
94962306a36Sopenharmony_ci		ohci_dbg(ohci, "resume detect\n");
95062306a36Sopenharmony_ci		ohci_writel(ohci, OHCI_INTR_RD, &regs->intrstatus);
95162306a36Sopenharmony_ci		set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
95262306a36Sopenharmony_ci		if (ohci->autostop) {
95362306a36Sopenharmony_ci			spin_lock (&ohci->lock);
95462306a36Sopenharmony_ci			ohci_rh_resume (ohci);
95562306a36Sopenharmony_ci			spin_unlock (&ohci->lock);
95662306a36Sopenharmony_ci		} else
95762306a36Sopenharmony_ci			usb_hcd_resume_root_hub(hcd);
95862306a36Sopenharmony_ci	}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	spin_lock(&ohci->lock);
96162306a36Sopenharmony_ci	if (ints & OHCI_INTR_WDH)
96262306a36Sopenharmony_ci		update_done_list(ohci);
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	/* could track INTR_SO to reduce available PCI/... bandwidth */
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	/* handle any pending URB/ED unlinks, leaving INTR_SF enabled
96762306a36Sopenharmony_ci	 * when there's still unlinking to be done (next frame).
96862306a36Sopenharmony_ci	 */
96962306a36Sopenharmony_ci	ohci_work(ohci);
97062306a36Sopenharmony_ci	if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
97162306a36Sopenharmony_ci			&& ohci->rh_state == OHCI_RH_RUNNING)
97262306a36Sopenharmony_ci		ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci	if (ohci->rh_state == OHCI_RH_RUNNING) {
97562306a36Sopenharmony_ci		ohci_writel (ohci, ints, &regs->intrstatus);
97662306a36Sopenharmony_ci		if (ints & OHCI_INTR_WDH)
97762306a36Sopenharmony_ci			++ohci->wdh_cnt;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci		ohci_writel (ohci, OHCI_INTR_MIE, &regs->intrenable);
98062306a36Sopenharmony_ci		// flush those writes
98162306a36Sopenharmony_ci		(void) ohci_readl (ohci, &ohci->regs->control);
98262306a36Sopenharmony_ci	}
98362306a36Sopenharmony_ci	spin_unlock(&ohci->lock);
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	return IRQ_HANDLED;
98662306a36Sopenharmony_ci}
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_cistatic void ohci_stop (struct usb_hcd *hcd)
99162306a36Sopenharmony_ci{
99262306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	ohci_dump(ohci);
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	if (quirk_nec(ohci))
99762306a36Sopenharmony_ci		flush_work(&ohci->nec_work);
99862306a36Sopenharmony_ci	del_timer_sync(&ohci->io_watchdog);
99962306a36Sopenharmony_ci	ohci->prev_frame_no = IO_WATCHDOG_OFF;
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
100262306a36Sopenharmony_ci	ohci_usb_reset(ohci);
100362306a36Sopenharmony_ci	free_irq(hcd->irq, hcd);
100462306a36Sopenharmony_ci	hcd->irq = 0;
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	if (quirk_amdiso(ohci))
100762306a36Sopenharmony_ci		usb_amd_dev_put();
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	remove_debug_files (ohci);
101062306a36Sopenharmony_ci	ohci_mem_cleanup (ohci);
101162306a36Sopenharmony_ci	if (ohci->hcca) {
101262306a36Sopenharmony_ci		if (hcd->localmem_pool)
101362306a36Sopenharmony_ci			gen_pool_free(hcd->localmem_pool,
101462306a36Sopenharmony_ci				      (unsigned long)ohci->hcca,
101562306a36Sopenharmony_ci				      sizeof(*ohci->hcca));
101662306a36Sopenharmony_ci		else
101762306a36Sopenharmony_ci			dma_free_coherent(hcd->self.controller,
101862306a36Sopenharmony_ci					  sizeof(*ohci->hcca),
101962306a36Sopenharmony_ci					  ohci->hcca, ohci->hcca_dma);
102062306a36Sopenharmony_ci		ohci->hcca = NULL;
102162306a36Sopenharmony_ci		ohci->hcca_dma = 0;
102262306a36Sopenharmony_ci	}
102362306a36Sopenharmony_ci}
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci#if defined(CONFIG_PM) || defined(CONFIG_USB_PCI)
102862306a36Sopenharmony_ci
102962306a36Sopenharmony_ci/* must not be called from interrupt context */
103062306a36Sopenharmony_ciint ohci_restart(struct ohci_hcd *ohci)
103162306a36Sopenharmony_ci{
103262306a36Sopenharmony_ci	int temp;
103362306a36Sopenharmony_ci	int i;
103462306a36Sopenharmony_ci	struct urb_priv *priv;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	ohci_init(ohci);
103762306a36Sopenharmony_ci	spin_lock_irq(&ohci->lock);
103862306a36Sopenharmony_ci	ohci->rh_state = OHCI_RH_HALTED;
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci	/* Recycle any "live" eds/tds (and urbs). */
104162306a36Sopenharmony_ci	if (!list_empty (&ohci->pending))
104262306a36Sopenharmony_ci		ohci_dbg(ohci, "abort schedule...\n");
104362306a36Sopenharmony_ci	list_for_each_entry (priv, &ohci->pending, pending) {
104462306a36Sopenharmony_ci		struct urb	*urb = priv->td[0]->urb;
104562306a36Sopenharmony_ci		struct ed	*ed = priv->ed;
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci		switch (ed->state) {
104862306a36Sopenharmony_ci		case ED_OPER:
104962306a36Sopenharmony_ci			ed->state = ED_UNLINK;
105062306a36Sopenharmony_ci			ed->hwINFO |= cpu_to_hc32(ohci, ED_DEQUEUE);
105162306a36Sopenharmony_ci			ed_deschedule (ohci, ed);
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci			ed->ed_next = ohci->ed_rm_list;
105462306a36Sopenharmony_ci			ed->ed_prev = NULL;
105562306a36Sopenharmony_ci			ohci->ed_rm_list = ed;
105662306a36Sopenharmony_ci			fallthrough;
105762306a36Sopenharmony_ci		case ED_UNLINK:
105862306a36Sopenharmony_ci			break;
105962306a36Sopenharmony_ci		default:
106062306a36Sopenharmony_ci			ohci_dbg(ohci, "bogus ed %p state %d\n",
106162306a36Sopenharmony_ci					ed, ed->state);
106262306a36Sopenharmony_ci		}
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci		if (!urb->unlinked)
106562306a36Sopenharmony_ci			urb->unlinked = -ESHUTDOWN;
106662306a36Sopenharmony_ci	}
106762306a36Sopenharmony_ci	ohci_work(ohci);
106862306a36Sopenharmony_ci	spin_unlock_irq(&ohci->lock);
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	/* paranoia, in case that didn't work: */
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	/* empty the interrupt branches */
107362306a36Sopenharmony_ci	for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0;
107462306a36Sopenharmony_ci	for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0;
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_ci	/* no EDs to remove */
107762306a36Sopenharmony_ci	ohci->ed_rm_list = NULL;
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ci	/* empty control and bulk lists */
108062306a36Sopenharmony_ci	ohci->ed_controltail = NULL;
108162306a36Sopenharmony_ci	ohci->ed_bulktail    = NULL;
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci	if ((temp = ohci_run (ohci)) < 0) {
108462306a36Sopenharmony_ci		ohci_err (ohci, "can't restart, %d\n", temp);
108562306a36Sopenharmony_ci		return temp;
108662306a36Sopenharmony_ci	}
108762306a36Sopenharmony_ci	ohci_dbg(ohci, "restart complete\n");
108862306a36Sopenharmony_ci	return 0;
108962306a36Sopenharmony_ci}
109062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ohci_restart);
109162306a36Sopenharmony_ci
109262306a36Sopenharmony_ci#endif
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci#ifdef CONFIG_PM
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ciint ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
109762306a36Sopenharmony_ci{
109862306a36Sopenharmony_ci	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
109962306a36Sopenharmony_ci	unsigned long	flags;
110062306a36Sopenharmony_ci	int		rc = 0;
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_ci	/* Disable irq emission and mark HW unaccessible. Use
110362306a36Sopenharmony_ci	 * the spinlock to properly synchronize with possible pending
110462306a36Sopenharmony_ci	 * RH suspend or resume activity.
110562306a36Sopenharmony_ci	 */
110662306a36Sopenharmony_ci	spin_lock_irqsave (&ohci->lock, flags);
110762306a36Sopenharmony_ci	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
110862306a36Sopenharmony_ci	(void)ohci_readl(ohci, &ohci->regs->intrdisable);
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
111162306a36Sopenharmony_ci	spin_unlock_irqrestore (&ohci->lock, flags);
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci	synchronize_irq(hcd->irq);
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_ci	if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) {
111662306a36Sopenharmony_ci		ohci_resume(hcd, false);
111762306a36Sopenharmony_ci		rc = -EBUSY;
111862306a36Sopenharmony_ci	}
111962306a36Sopenharmony_ci	return rc;
112062306a36Sopenharmony_ci}
112162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ohci_suspend);
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ciint ohci_resume(struct usb_hcd *hcd, bool hibernated)
112562306a36Sopenharmony_ci{
112662306a36Sopenharmony_ci	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
112762306a36Sopenharmony_ci	int			port;
112862306a36Sopenharmony_ci	bool			need_reinit = false;
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci	/* Make sure resume from hibernation re-enumerates everything */
113362306a36Sopenharmony_ci	if (hibernated)
113462306a36Sopenharmony_ci		ohci_usb_reset(ohci);
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ci	/* See if the controller is already running or has been reset */
113762306a36Sopenharmony_ci	ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
113862306a36Sopenharmony_ci	if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
113962306a36Sopenharmony_ci		need_reinit = true;
114062306a36Sopenharmony_ci	} else {
114162306a36Sopenharmony_ci		switch (ohci->hc_control & OHCI_CTRL_HCFS) {
114262306a36Sopenharmony_ci		case OHCI_USB_OPER:
114362306a36Sopenharmony_ci		case OHCI_USB_RESET:
114462306a36Sopenharmony_ci			need_reinit = true;
114562306a36Sopenharmony_ci		}
114662306a36Sopenharmony_ci	}
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_ci	/* If needed, reinitialize and suspend the root hub */
114962306a36Sopenharmony_ci	if (need_reinit) {
115062306a36Sopenharmony_ci		spin_lock_irq(&ohci->lock);
115162306a36Sopenharmony_ci		ohci_rh_resume(ohci);
115262306a36Sopenharmony_ci		ohci_rh_suspend(ohci, 0);
115362306a36Sopenharmony_ci		spin_unlock_irq(&ohci->lock);
115462306a36Sopenharmony_ci	}
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci	/* Normally just turn on port power and enable interrupts */
115762306a36Sopenharmony_ci	else {
115862306a36Sopenharmony_ci		ohci_dbg(ohci, "powerup ports\n");
115962306a36Sopenharmony_ci		for (port = 0; port < ohci->num_ports; port++)
116062306a36Sopenharmony_ci			ohci_writel(ohci, RH_PS_PPS,
116162306a36Sopenharmony_ci					&ohci->regs->roothub.portstatus[port]);
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci		ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
116462306a36Sopenharmony_ci		ohci_readl(ohci, &ohci->regs->intrenable);
116562306a36Sopenharmony_ci		msleep(20);
116662306a36Sopenharmony_ci	}
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci	usb_hcd_resume_root_hub(hcd);
116962306a36Sopenharmony_ci
117062306a36Sopenharmony_ci	return 0;
117162306a36Sopenharmony_ci}
117262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ohci_resume);
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci#endif
117562306a36Sopenharmony_ci
117662306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci/*
117962306a36Sopenharmony_ci * Generic structure: This gets copied for platform drivers so that
118062306a36Sopenharmony_ci * individual entries can be overridden as needed.
118162306a36Sopenharmony_ci */
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_cistatic const struct hc_driver ohci_hc_driver = {
118462306a36Sopenharmony_ci	.description =          hcd_name,
118562306a36Sopenharmony_ci	.product_desc =         "OHCI Host Controller",
118662306a36Sopenharmony_ci	.hcd_priv_size =        sizeof(struct ohci_hcd),
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci	/*
118962306a36Sopenharmony_ci	 * generic hardware linkage
119062306a36Sopenharmony_ci	*/
119162306a36Sopenharmony_ci	.irq =                  ohci_irq,
119262306a36Sopenharmony_ci	.flags =                HCD_MEMORY | HCD_DMA | HCD_USB11,
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	/*
119562306a36Sopenharmony_ci	* basic lifecycle operations
119662306a36Sopenharmony_ci	*/
119762306a36Sopenharmony_ci	.reset =                ohci_setup,
119862306a36Sopenharmony_ci	.start =                ohci_start,
119962306a36Sopenharmony_ci	.stop =                 ohci_stop,
120062306a36Sopenharmony_ci	.shutdown =             ohci_shutdown,
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	/*
120362306a36Sopenharmony_ci	 * managing i/o requests and associated device resources
120462306a36Sopenharmony_ci	*/
120562306a36Sopenharmony_ci	.urb_enqueue =          ohci_urb_enqueue,
120662306a36Sopenharmony_ci	.urb_dequeue =          ohci_urb_dequeue,
120762306a36Sopenharmony_ci	.endpoint_disable =     ohci_endpoint_disable,
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci	/*
121062306a36Sopenharmony_ci	* scheduling support
121162306a36Sopenharmony_ci	*/
121262306a36Sopenharmony_ci	.get_frame_number =     ohci_get_frame,
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci	/*
121562306a36Sopenharmony_ci	* root hub support
121662306a36Sopenharmony_ci	*/
121762306a36Sopenharmony_ci	.hub_status_data =      ohci_hub_status_data,
121862306a36Sopenharmony_ci	.hub_control =          ohci_hub_control,
121962306a36Sopenharmony_ci#ifdef CONFIG_PM
122062306a36Sopenharmony_ci	.bus_suspend =          ohci_bus_suspend,
122162306a36Sopenharmony_ci	.bus_resume =           ohci_bus_resume,
122262306a36Sopenharmony_ci#endif
122362306a36Sopenharmony_ci	.start_port_reset =	ohci_start_port_reset,
122462306a36Sopenharmony_ci};
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_civoid ohci_init_driver(struct hc_driver *drv,
122762306a36Sopenharmony_ci		const struct ohci_driver_overrides *over)
122862306a36Sopenharmony_ci{
122962306a36Sopenharmony_ci	/* Copy the generic table to drv and then apply the overrides */
123062306a36Sopenharmony_ci	*drv = ohci_hc_driver;
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci	if (over) {
123362306a36Sopenharmony_ci		drv->product_desc = over->product_desc;
123462306a36Sopenharmony_ci		drv->hcd_priv_size += over->extra_priv_size;
123562306a36Sopenharmony_ci		if (over->reset)
123662306a36Sopenharmony_ci			drv->reset = over->reset;
123762306a36Sopenharmony_ci	}
123862306a36Sopenharmony_ci}
123962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ohci_init_driver);
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ciMODULE_AUTHOR (DRIVER_AUTHOR);
124462306a36Sopenharmony_ciMODULE_DESCRIPTION(DRIVER_DESC);
124562306a36Sopenharmony_ciMODULE_LICENSE ("GPL");
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_SA1111)
124862306a36Sopenharmony_ci#include "ohci-sa1111.c"
124962306a36Sopenharmony_ci#define SA1111_DRIVER		ohci_hcd_sa1111_driver
125062306a36Sopenharmony_ci#endif
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
125362306a36Sopenharmony_ci#include "ohci-ppc-of.c"
125462306a36Sopenharmony_ci#define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
125562306a36Sopenharmony_ci#endif
125662306a36Sopenharmony_ci
125762306a36Sopenharmony_ci#ifdef CONFIG_PPC_PS3
125862306a36Sopenharmony_ci#include "ohci-ps3.c"
125962306a36Sopenharmony_ci#define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
126062306a36Sopenharmony_ci#endif
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci#ifdef CONFIG_MFD_SM501
126362306a36Sopenharmony_ci#include "ohci-sm501.c"
126462306a36Sopenharmony_ci#define SM501_OHCI_DRIVER	ohci_hcd_sm501_driver
126562306a36Sopenharmony_ci#endif
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_cistatic int __init ohci_hcd_mod_init(void)
126862306a36Sopenharmony_ci{
126962306a36Sopenharmony_ci	int retval = 0;
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	if (usb_disabled())
127262306a36Sopenharmony_ci		return -ENODEV;
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ci	pr_debug ("%s: block sizes: ed %zd td %zd\n", hcd_name,
127562306a36Sopenharmony_ci		sizeof (struct ed), sizeof (struct td));
127662306a36Sopenharmony_ci	set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci	ohci_debug_root = debugfs_create_dir("ohci", usb_debug_root);
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_ci#ifdef PS3_SYSTEM_BUS_DRIVER
128162306a36Sopenharmony_ci	retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
128262306a36Sopenharmony_ci	if (retval < 0)
128362306a36Sopenharmony_ci		goto error_ps3;
128462306a36Sopenharmony_ci#endif
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci#ifdef OF_PLATFORM_DRIVER
128762306a36Sopenharmony_ci	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
128862306a36Sopenharmony_ci	if (retval < 0)
128962306a36Sopenharmony_ci		goto error_of_platform;
129062306a36Sopenharmony_ci#endif
129162306a36Sopenharmony_ci
129262306a36Sopenharmony_ci#ifdef SA1111_DRIVER
129362306a36Sopenharmony_ci	retval = sa1111_driver_register(&SA1111_DRIVER);
129462306a36Sopenharmony_ci	if (retval < 0)
129562306a36Sopenharmony_ci		goto error_sa1111;
129662306a36Sopenharmony_ci#endif
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci#ifdef SM501_OHCI_DRIVER
129962306a36Sopenharmony_ci	retval = platform_driver_register(&SM501_OHCI_DRIVER);
130062306a36Sopenharmony_ci	if (retval < 0)
130162306a36Sopenharmony_ci		goto error_sm501;
130262306a36Sopenharmony_ci#endif
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci	return retval;
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	/* Error path */
130762306a36Sopenharmony_ci#ifdef SM501_OHCI_DRIVER
130862306a36Sopenharmony_ci	platform_driver_unregister(&SM501_OHCI_DRIVER);
130962306a36Sopenharmony_ci error_sm501:
131062306a36Sopenharmony_ci#endif
131162306a36Sopenharmony_ci#ifdef SA1111_DRIVER
131262306a36Sopenharmony_ci	sa1111_driver_unregister(&SA1111_DRIVER);
131362306a36Sopenharmony_ci error_sa1111:
131462306a36Sopenharmony_ci#endif
131562306a36Sopenharmony_ci#ifdef OF_PLATFORM_DRIVER
131662306a36Sopenharmony_ci	platform_driver_unregister(&OF_PLATFORM_DRIVER);
131762306a36Sopenharmony_ci error_of_platform:
131862306a36Sopenharmony_ci#endif
131962306a36Sopenharmony_ci#ifdef PS3_SYSTEM_BUS_DRIVER
132062306a36Sopenharmony_ci	ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
132162306a36Sopenharmony_ci error_ps3:
132262306a36Sopenharmony_ci#endif
132362306a36Sopenharmony_ci	debugfs_remove(ohci_debug_root);
132462306a36Sopenharmony_ci	ohci_debug_root = NULL;
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
132762306a36Sopenharmony_ci	return retval;
132862306a36Sopenharmony_ci}
132962306a36Sopenharmony_cimodule_init(ohci_hcd_mod_init);
133062306a36Sopenharmony_ci
133162306a36Sopenharmony_cistatic void __exit ohci_hcd_mod_exit(void)
133262306a36Sopenharmony_ci{
133362306a36Sopenharmony_ci#ifdef SM501_OHCI_DRIVER
133462306a36Sopenharmony_ci	platform_driver_unregister(&SM501_OHCI_DRIVER);
133562306a36Sopenharmony_ci#endif
133662306a36Sopenharmony_ci#ifdef SA1111_DRIVER
133762306a36Sopenharmony_ci	sa1111_driver_unregister(&SA1111_DRIVER);
133862306a36Sopenharmony_ci#endif
133962306a36Sopenharmony_ci#ifdef OF_PLATFORM_DRIVER
134062306a36Sopenharmony_ci	platform_driver_unregister(&OF_PLATFORM_DRIVER);
134162306a36Sopenharmony_ci#endif
134262306a36Sopenharmony_ci#ifdef PS3_SYSTEM_BUS_DRIVER
134362306a36Sopenharmony_ci	ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
134462306a36Sopenharmony_ci#endif
134562306a36Sopenharmony_ci	debugfs_remove(ohci_debug_root);
134662306a36Sopenharmony_ci	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
134762306a36Sopenharmony_ci}
134862306a36Sopenharmony_cimodule_exit(ohci_hcd_mod_exit);
134962306a36Sopenharmony_ci
1350