Commit b5fb454f authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: automatically enable RHSC interrupts



This patch (as1069c) changes the way OHCI root-hub status-change
interrupts are enabled.  Currently a special HCD method,
hub_irq_enable(), is called when the hub driver is finished using a
root hub.  This approach turns out to be subject to races, resulting
in unnecessary polling.

The patch does away with the method entirely.  Instead, the driver
automatically enables the RHSC interrupt when no more status changes
are present.  This scheme is safe with controllers using
level-triggered semantics for their interrupt flags.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5096aedc
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -924,15 +924,6 @@ static int register_root_hub(struct usb_hcd *hcd)
	return retval;
}

void usb_enable_root_hub_irq (struct usb_bus *bus)
{
	struct usb_hcd *hcd;

	hcd = container_of (bus, struct usb_hcd, self);
	if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
		hcd->driver->hub_irq_enable (hcd);
}


/*-------------------------------------------------------------------------*/

+0 −4
Original line number Diff line number Diff line
@@ -212,8 +212,6 @@ struct hc_driver {
	int	(*bus_suspend)(struct usb_hcd *);
	int	(*bus_resume)(struct usb_hcd *);
	int	(*start_port_reset)(struct usb_hcd *, unsigned port_num);
	void	(*hub_irq_enable)(struct usb_hcd *);
		/* Needed only if port-change IRQs are level-triggered */

		/* force handover of high-speed port to full-speed companion */
	void	(*relinquish_port)(struct usb_hcd *, int);
@@ -379,8 +377,6 @@ extern struct list_head usb_bus_list;
extern struct mutex usb_bus_list_lock;
extern wait_queue_head_t usb_kill_urb_queue;

extern void usb_enable_root_hub_irq(struct usb_bus *bus);

extern int usb_find_interface_driver(struct usb_device *dev,
	struct usb_interface *interface);

+0 −9
Original line number Diff line number Diff line
@@ -2102,8 +2102,6 @@ int usb_port_resume(struct usb_device *udev)
	}

	clear_bit(port1, hub->busy_bits);
	if (!hub->hdev->parent && !hub->busy_bits[0])
		usb_enable_root_hub_irq(hub->hdev->bus);

	status = check_port_resume_type(udev,
			hub, port1, status, portchange, portstatus);
@@ -3081,11 +3079,6 @@ static void hub_events(void)
			}
		}

		/* If this is a root hub, tell the HCD it's okay to
		 * re-enable port-change interrupts now. */
		if (!hdev->parent && !hub->busy_bits[0])
			usb_enable_root_hub_irq(hdev->bus);

loop_autopm:
		/* Allow autosuspend if we're not going to run again */
		if (list_empty(&hub->event_list))
@@ -3311,8 +3304,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
			break;
	}
	clear_bit(port1, parent_hub->busy_bits);
	if (!parent_hdev->parent && !parent_hub->busy_bits[0])
		usb_enable_root_hub_irq(parent_hdev->bus);

	if (ret < 0)
		goto re_enumerate;
+0 −1
Original line number Diff line number Diff line
@@ -260,7 +260,6 @@ static const struct hc_driver ohci_at91_hc_driver = {
	 */
	.hub_status_data =	ohci_hub_status_data,
	.hub_control =		ohci_hub_control,
	.hub_irq_enable =	ohci_rhsc_enable,
#ifdef CONFIG_PM
	.bus_suspend =		ohci_bus_suspend,
	.bus_resume =		ohci_bus_resume,
+0 −1
Original line number Diff line number Diff line
@@ -163,7 +163,6 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
	 */
	.hub_status_data =	ohci_hub_status_data,
	.hub_control =		ohci_hub_control,
	.hub_irq_enable =	ohci_rhsc_enable,
#ifdef	CONFIG_PM
	.bus_suspend =		ohci_bus_suspend,
	.bus_resume =		ohci_bus_resume,
Loading