aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/int.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2008-09-17 11:34:28 -0400
committerDavid Vrabel <dv02@dv02pc01.europe.root.pri>2008-09-17 11:54:31 -0400
commit7e6133aa42920ea87ad9791a0fb2b95d1a23b8f9 (patch)
treeaa686de823ea3246b6c5cd2e4ef0e54e3797c3e3 /drivers/usb/host/whci/int.c
parent870d5395045bfe8e5213525152682c863a10f8d2 (diff)
wusb: WHCI host controller driver
A driver for Wireless USB host controllers that comply with the Wireless Host Controller Interface (HCI) specification as published by Intel. The latest publically available version of the specification (0.95) is supported (except for isochronous transfers). Build fixes by Randy Dunlap <rdunlap@xenotime.net> Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/usb/host/whci/int.c')
-rw-r--r--drivers/usb/host/whci/int.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c
new file mode 100644
index 000000000000..fce01174aa9b
--- /dev/null
+++ b/drivers/usb/host/whci/int.c
@@ -0,0 +1,95 @@
1/*
2 * Wireless Host Controller (WHC) interrupt handling.
3 *
4 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/uwb/umc.h>
22
23#include "../../wusbcore/wusbhc.h"
24
25#include "whcd.h"
26
27static void transfer_done(struct whc *whc)
28{
29 queue_work(whc->workqueue, &whc->async_work);
30 queue_work(whc->workqueue, &whc->periodic_work);
31}
32
33irqreturn_t whc_int_handler(struct usb_hcd *hcd)
34{
35 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(hcd);
36 struct whc *whc = wusbhc_to_whc(wusbhc);
37 u32 sts;
38
39 sts = le_readl(whc->base + WUSBSTS);
40 if (!(sts & WUSBSTS_INT_MASK))
41 return IRQ_NONE;
42 le_writel(sts & WUSBSTS_INT_MASK, whc->base + WUSBSTS);
43
44 if (sts & WUSBSTS_GEN_CMD_DONE)
45 wake_up(&whc->cmd_wq);
46
47 if (sts & WUSBSTS_HOST_ERR)
48 dev_err(&whc->umc->dev, "FIXME: host system error\n");
49
50 if (sts & WUSBSTS_ASYNC_SCHED_SYNCED)
51 wake_up(&whc->async_list_wq);
52
53 if (sts & WUSBSTS_PERIODIC_SCHED_SYNCED)
54 wake_up(&whc->periodic_list_wq);
55
56 if (sts & WUSBSTS_DNTS_INT)
57 queue_work(whc->workqueue, &whc->dn_work);
58
59 /*
60 * A transfer completed (see [WHCI] section 4.7.1.2 for when
61 * this occurs).
62 */
63 if (sts & (WUSBSTS_INT | WUSBSTS_ERR_INT))
64 transfer_done(whc);
65
66 return IRQ_HANDLED;
67}
68
69static int process_dn_buf(struct whc *whc)
70{
71 struct wusbhc *wusbhc = &whc->wusbhc;
72 struct dn_buf_entry *dn;
73 int processed = 0;
74
75 for (dn = whc->dn_buf; dn < whc->dn_buf + WHC_N_DN_ENTRIES; dn++) {
76 if (dn->status & WHC_DN_STATUS_VALID) {
77 wusbhc_handle_dn(wusbhc, dn->src_addr,
78 (struct wusb_dn_hdr *)dn->dn_data,
79 dn->msg_size);
80 dn->status &= ~WHC_DN_STATUS_VALID;
81 processed++;
82 }
83 }
84 return processed;
85}
86
87void whc_dn_work(struct work_struct *work)
88{
89 struct whc *whc = container_of(work, struct whc, dn_work);
90 int processed;
91
92 do {
93 processed = process_dn_buf(whc);
94 } while (processed);
95}