aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/host/whci
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-09 14:58:11 +0100
committerIngo Molnar <mingo@elte.hu>2009-02-09 14:58:11 +0100
commit249d51b53aea1b7cdb1be65a1a9a0c59d9e06f3e (patch)
tree7fc06930e46ee13d394f5b031166c40206af3189 /drivers/usb/host/whci
parent44581a28e805a31661469c4b466b9cd14b36e7b6 (diff)
parent8e4921515c1a379539607eb443d51c30f4f7f338 (diff)
Merge commit 'v2.6.29-rc4' into core/percpu
Conflicts: arch/x86/mach-voyager/voyager_smp.c arch/x86/mm/fault.c
Diffstat (limited to 'drivers/usb/host/whci')
-rw-r--r--drivers/usb/host/whci/asl.c9
-rw-r--r--drivers/usb/host/whci/hw.c15
-rw-r--r--drivers/usb/host/whci/pzl.c9
-rw-r--r--drivers/usb/host/whci/whcd.h1
4 files changed, 30 insertions, 4 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 577c0d29849..2291c5f5af5 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -170,12 +170,17 @@ void asl_stop(struct whc *whc)
void asl_update(struct whc *whc, uint32_t wusbcmd)
{
struct wusbhc *wusbhc = &whc->wusbhc;
+ long t;
mutex_lock(&wusbhc->mutex);
if (wusbhc->active) {
whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
- wait_event(whc->async_list_wq,
- (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
+ t = wait_event_timeout(
+ whc->async_list_wq,
+ (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0,
+ msecs_to_jiffies(1000));
+ if (t == 0)
+ whc_hw_error(whc, "ASL update timeout");
}
mutex_unlock(&wusbhc->mutex);
}
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index d498e720321..6afa2e37916 100644
--- a/drivers/usb/host/whci/hw.c
+++ b/drivers/usb/host/whci/hw.c
@@ -87,3 +87,18 @@ out:
return ret;
}
+
+/**
+ * whc_hw_error - recover from a hardware error
+ * @whc: the WHCI HC that broke.
+ * @reason: a description of the failure.
+ *
+ * Recover from broken hardware with a full reset.
+ */
+void whc_hw_error(struct whc *whc, const char *reason)
+{
+ struct wusbhc *wusbhc = &whc->wusbhc;
+
+ dev_err(&whc->umc->dev, "hardware error: %s\n", reason);
+ wusbhc_reset_all(wusbhc);
+}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 2ae5abf69a6..7dc85a0bee7 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc)
void pzl_update(struct whc *whc, uint32_t wusbcmd)
{
struct wusbhc *wusbhc = &whc->wusbhc;
+ long t;
mutex_lock(&wusbhc->mutex);
if (wusbhc->active) {
whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
- wait_event(whc->periodic_list_wq,
- (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
+ t = wait_event_timeout(
+ whc->periodic_list_wq,
+ (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0,
+ msecs_to_jiffies(1000));
+ if (t == 0)
+ whc_hw_error(whc, "PZL update timeout");
}
mutex_unlock(&wusbhc->mutex);
}
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 0f3540f04f5..d3543a181dc 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc);
/* hw.c */
void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
+void whc_hw_error(struct whc *whc, const char *reason);
/* wusb.c */
int whc_wusbhc_start(struct wusbhc *wusbhc);