Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 317034
b: refs/heads/master
c: 18aafe6
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jul 16, 2012
1 parent 24bf1b1 commit 201bf10
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 66 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 569b394f53f0abd177cc665c9b4ace89e3f4c7fb
refs/heads/master: 18aafe64d75d0e27dae206cacf4171e4e485d285
47 changes: 1 addition & 46 deletions trunk/drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ static const char hcd_name [] = "ehci_hcd";
*/
#define EHCI_TUNE_FLS 1 /* (medium) 512-frame schedule */

#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */

/* Initial IRQ latency: faster than hw default */
static int log2_irq_thresh = 0; // 0 to 6
module_param (log2_irq_thresh, int, S_IRUGO);
Expand Down Expand Up @@ -125,25 +123,6 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");

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

static void
timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
{
if (!test_and_set_bit(action, &ehci->actions)) {
unsigned long t;

switch (action) {
case TIMER_IO_WATCHDOG:
if (!ehci->need_io_watchdog)
return;
t = EHCI_IO_JIFFIES;
break;
}
mod_timer(&ehci->watchdog, t + jiffies);
}
}

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

/*
* handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
Expand Down Expand Up @@ -307,19 +286,6 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);

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

static void ehci_watchdog(unsigned long param)
{
struct ehci_hcd *ehci = (struct ehci_hcd *) param;
unsigned long flags;

spin_lock_irqsave(&ehci->lock, flags);

/* ehci could run by timer, without IRQs ... */
ehci_work (ehci);

spin_unlock_irqrestore (&ehci->lock, flags);
}

/* On some systems, leaving remote wakeup enabled prevents system shutdown.
* The firmware seems to think that powering off is a wakeup event!
* This routine turns off remote wakeup and everything else, on all ports.
Expand Down Expand Up @@ -357,8 +323,6 @@ static void ehci_shutdown(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);

del_timer_sync(&ehci->watchdog);

spin_lock_irq(&ehci->lock);
ehci->rh_state = EHCI_RH_STOPPING;
ehci_silence_controller(ehci);
Expand Down Expand Up @@ -394,8 +358,6 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
*/
static void ehci_work (struct ehci_hcd *ehci)
{
timer_action_done (ehci, TIMER_IO_WATCHDOG);

/* another CPU may drop ehci->lock during a schedule scan while
* it reports urb completions. this flag guards against bogus
* attempts at re-entrant schedule scanning.
Expand All @@ -422,10 +384,7 @@ static void ehci_work (struct ehci_hcd *ehci)
* misplace IRQs, and should let us run completely without IRQs.
* such lossage has been observed on both VT6202 and VT8235.
*/
if (ehci->rh_state == EHCI_RH_RUNNING &&
(ehci->async->qh_next.ptr != NULL ||
ehci->periodic_count != 0))
timer_action (ehci, TIMER_IO_WATCHDOG);
turn_on_io_watchdog(ehci);
}

/*
Expand All @@ -438,7 +397,6 @@ static void ehci_stop (struct usb_hcd *hcd)
ehci_dbg (ehci, "stop\n");

/* no more interrupts ... */
del_timer_sync (&ehci->watchdog);

spin_lock_irq(&ehci->lock);
ehci->enabled_hrtimer_events = 0;
Expand Down Expand Up @@ -490,9 +448,6 @@ static int ehci_init(struct usb_hcd *hcd)
* keep io watchdog by default, those good HCDs could turn off it later
*/
ehci->need_io_watchdog = 1;
init_timer(&ehci->watchdog);
ehci->watchdog.function = ehci_watchdog;
ehci->watchdog.data = (unsigned long) ehci;

hrtimer_init(&ehci->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
ehci->hrtimer.function = ehci_hrtimer_func;
Expand Down
5 changes: 0 additions & 5 deletions trunk/drivers/usb/host/ehci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)

if (time_before (jiffies, ehci->next_statechange))
msleep(5);
del_timer_sync(&ehci->watchdog);

spin_lock_irq (&ehci->lock);

Expand Down Expand Up @@ -316,10 +315,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT;
spin_unlock_irq (&ehci->lock);

/* ehci_work() may have re-enabled the watchdog timer, which we do not
* want, and so we must delete any pending watchdog timer events.
*/
del_timer_sync(&ehci->watchdog);
hrtimer_cancel(&ehci->hrtimer);
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci-q.c
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,7 @@ static void enable_async(struct ehci_hcd *ehci)

/* Don't start the schedule until ASS is 0 */
ehci_poll_ASS(ehci);
turn_on_io_watchdog(ehci);
}

static void disable_async(struct ehci_hcd *ehci)
Expand Down
3 changes: 1 addition & 2 deletions trunk/drivers/usb/host/ehci-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ static void enable_periodic(struct ehci_hcd *ehci)

/* Don't start the schedule until PSS is 0 */
ehci_poll_PSS(ehci);
turn_on_io_watchdog(ehci);
}

static void disable_periodic(struct ehci_hcd *ehci)
Expand Down Expand Up @@ -1649,7 +1650,6 @@ static void itd_link_urb(
iso_sched_free (stream, iso_sched);
urb->hcpriv = NULL;

timer_action (ehci, TIMER_IO_WATCHDOG);
++ehci->isoc_count;
enable_periodic(ehci);
}
Expand Down Expand Up @@ -2052,7 +2052,6 @@ static void sitd_link_urb(
iso_sched_free (stream, sched);
urb->hcpriv = NULL;

timer_action (ehci, TIMER_IO_WATCHDOG);
++ehci->isoc_count;
enable_periodic(ehci);
}
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/usb/host/ehci-timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static unsigned event_delays_ns[] = {
10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_IAA_WATCHDOG */
10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_DISABLE_PERIODIC */
15 * NSEC_PER_MSEC, /* EHCI_HRTIMER_DISABLE_ASYNC */
100 * NSEC_PER_MSEC, /* EHCI_HRTIMER_IO_WATCHDOG */
};

/* Enable a pending hrtimer event */
Expand Down Expand Up @@ -332,6 +333,25 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
}


/* Enable the I/O watchdog, if appropriate */
static void turn_on_io_watchdog(struct ehci_hcd *ehci)
{
/* Not needed if the controller isn't running or it's already enabled */
if (ehci->rh_state != EHCI_RH_RUNNING ||
(ehci->enabled_hrtimer_events &
BIT(EHCI_HRTIMER_IO_WATCHDOG)))
return;

/*
* Isochronous transfers always need the watchdog.
* For other sorts we use it only if the flag is set.
*/
if (ehci->isoc_count > 0 || (ehci->need_io_watchdog &&
ehci->async_count + ehci->intr_count > 0))
ehci_enable_event(ehci, EHCI_HRTIMER_IO_WATCHDOG, true);
}


/*
* Handler functions for the hrtimer event types.
* Keep this array in the same order as the event types indexed by
Expand All @@ -347,6 +367,7 @@ static void (*event_handlers[])(struct ehci_hcd *) = {
ehci_iaa_watchdog, /* EHCI_HRTIMER_IAA_WATCHDOG */
ehci_disable_PSE, /* EHCI_HRTIMER_DISABLE_PERIODIC */
ehci_disable_ASE, /* EHCI_HRTIMER_DISABLE_ASYNC */
ehci_work, /* EHCI_HRTIMER_IO_WATCHDOG */
};

static enum hrtimer_restart ehci_hrtimer_func(struct hrtimer *t)
Expand Down
13 changes: 1 addition & 12 deletions trunk/drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ enum ehci_hrtimer_event {
EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */
EHCI_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
EHCI_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */
EHCI_HRTIMER_IO_WATCHDOG, /* Check for missing IRQs */
EHCI_HRTIMER_NUM_EVENTS /* Must come last */
};
#define EHCI_HRTIMER_NO_EVENT 99
Expand Down Expand Up @@ -177,8 +178,6 @@ struct ehci_hcd { /* one per controller */
struct dma_pool *itd_pool; /* itd per iso urb */
struct dma_pool *sitd_pool; /* sitd per split iso urb */

struct timer_list watchdog;
unsigned long actions;
unsigned random_frame;
unsigned long next_statechange;
ktime_t last_periodic_enable;
Expand Down Expand Up @@ -235,16 +234,6 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci)
return container_of ((void *) ehci, struct usb_hcd, hcd_priv);
}

enum ehci_timer_action {
TIMER_IO_WATCHDOG,
};

static inline void
timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
{
clear_bit (action, &ehci->actions);
}

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

#include <linux/usb/ehci_def.h>
Expand Down

0 comments on commit 201bf10

Please sign in to comment.