Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a9cdf33 authored by Alek Du's avatar Alek Du Committed by Greg Kroah-Hartman
Browse files

USB: EHCI: EHCI 1.1 addendum: Enable Per-port change detect bits



This patch will enable Per-port event feature defined in EHCI 1.1
addendum. This feature addresses an issue where HCD is currently
required to read and parse PORTSC for all enabled root hub ports. With
this patch, the overhead will be reduced.

Signed-off-by: default avatarAlek Du <alek.du@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 48f24970
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -584,6 +584,11 @@ static int ehci_init(struct usb_hcd *hcd)
	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
		log2_irq_thresh = 0;
	temp = 1 << (16 + log2_irq_thresh);
	if (HCC_PER_PORT_CHANGE_EVENT(hcc_params)) {
		ehci->has_ppcd = 1;
		ehci_dbg(ehci, "enable per-port change event\n");
		temp |= CMD_PPCEE;
	}
	if (HCC_CANPARK(hcc_params)) {
		/* HW default park == 3, on hardware that supports it (like
		 * NVidia and ALI silicon), maximizes throughput on the async
@@ -782,6 +787,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
	/* remote wakeup [4.3.1] */
	if (status & STS_PCD) {
		unsigned	i = HCS_N_PORTS (ehci->hcs_params);
		u32		ppcd = 0;

		/* kick root hub later */
		pcd_status = status;
@@ -790,8 +796,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
		if (!(cmd & CMD_RUN))
			usb_hcd_resume_root_hub(hcd);

		/* get per-port change detect bits */
		if (ehci->has_ppcd)
			ppcd = status >> 16;

		while (i--) {
			int pstatus = ehci_readl(ehci,
			int pstatus;

			/* leverage per-port change bits feature */
			if (ehci->has_ppcd && !(ppcd & (1 << i)))
				continue;
			pstatus = ehci_readl(ehci,
					 &ehci->regs->port_status[i]);

			if (pstatus & PORT_OWNER)
+9 −0
Original line number Diff line number Diff line
@@ -603,6 +603,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
	u32		mask;
	int		ports, i, retval = 1;
	unsigned long	flags;
	u32		ppcd = 0;

	/* if !USB_SUSPEND, root hub timers won't get shut down ... */
	if (!HC_IS_RUNNING(hcd->state))
@@ -632,7 +633,15 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)

	/* port N changes (bit N)? */
	spin_lock_irqsave (&ehci->lock, flags);

	/* get per-port change detect bits */
	if (ehci->has_ppcd)
		ppcd = ehci_readl(ehci, &ehci->regs->status) >> 16;

	for (i = 0; i < ports; i++) {
		/* leverage per-port change bits feature */
		if (ehci->has_ppcd && !(ppcd & (1 << i)))
			continue;
		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);

		/*
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ struct ehci_hcd { /* one per controller */
	__hc32			*ohci_hcctrl_reg;
	unsigned		has_hostpc:1;
	unsigned		has_lpm:1;  /* support link power management */
	unsigned		has_ppcd:1; /* support per-port change bits */
	u8			sbrn;		/* packed release number */

	/* irq statistics */