Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
usb
host
whci
int.c
Go to the documentation of this file.
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/kernel.h>
19
#include <
linux/init.h
>
20
#include <
linux/uwb/umc.h
>
21
22
#include "../../wusbcore/wusbhc.h"
23
24
#include "
whcd.h
"
25
26
static
void
transfer_done(
struct
whc
*
whc
)
27
{
28
queue_work
(whc->
workqueue
, &whc->
async_work
);
29
queue_work
(whc->
workqueue
, &whc->
periodic_work
);
30
}
31
32
irqreturn_t
whc_int_handler
(
struct
usb_hcd *hcd)
33
{
34
struct
wusbhc
*
wusbhc
=
usb_hcd_to_wusbhc
(hcd);
35
struct
whc
*
whc
=
wusbhc_to_whc
(wusbhc);
36
u32
sts
;
37
38
sts = le_readl(whc->
base
+
WUSBSTS
);
39
if
(!(sts &
WUSBSTS_INT_MASK
))
40
return
IRQ_NONE
;
41
le_writel(sts & WUSBSTS_INT_MASK, whc->
base
+
WUSBSTS
);
42
43
if
(sts &
WUSBSTS_GEN_CMD_DONE
)
44
wake_up
(&whc->
cmd_wq
);
45
46
if
(sts &
WUSBSTS_HOST_ERR
)
47
dev_err
(&whc->
umc
->dev,
"FIXME: host system error\n"
);
48
49
if
(sts &
WUSBSTS_ASYNC_SCHED_SYNCED
)
50
wake_up
(&whc->
async_list_wq
);
51
52
if
(sts &
WUSBSTS_PERIODIC_SCHED_SYNCED
)
53
wake_up
(&whc->
periodic_list_wq
);
54
55
if
(sts &
WUSBSTS_DNTS_INT
)
56
queue_work
(whc->
workqueue
, &whc->
dn_work
);
57
58
/*
59
* A transfer completed (see [WHCI] section 4.7.1.2 for when
60
* this occurs).
61
*/
62
if
(sts & (
WUSBSTS_INT
|
WUSBSTS_ERR_INT
))
63
transfer_done(whc);
64
65
return
IRQ_HANDLED
;
66
}
67
68
static
int
process_dn_buf(
struct
whc
*
whc
)
69
{
70
struct
wusbhc
*
wusbhc
= &whc->
wusbhc
;
71
struct
dn_buf_entry
*
dn
;
72
int
processed = 0;
73
74
for
(dn = whc->
dn_buf
; dn < whc->dn_buf +
WHC_N_DN_ENTRIES
; dn++) {
75
if
(dn->
status
&
WHC_DN_STATUS_VALID
) {
76
wusbhc_handle_dn
(wusbhc, dn->
src_addr
,
77
(
struct
wusb_dn_hdr
*)dn->
dn_data
,
78
dn->
msg_size
);
79
dn->
status
&= ~
WHC_DN_STATUS_VALID
;
80
processed++;
81
}
82
}
83
return
processed;
84
}
85
86
void
whc_dn_work
(
struct
work_struct
*
work
)
87
{
88
struct
whc *whc =
container_of
(work,
struct
whc,
dn_work
);
89
int
processed;
90
91
do
{
92
processed = process_dn_buf(whc);
93
}
while
(processed);
94
}
Generated on Thu Jan 10 2013 13:12:08 for Linux Kernel by
1.8.2